Commit 4de6caa270afaa381dd3373e9e6d148b1090e0ec

Authored by Andy Adamson
Committed by Trond Myklebust
1 parent f1ff0c27fd

SUNRPC new rpc_credops to test credential expiry

This patch provides the RPC layer helper functions to allow NFS to manage
data in the face of expired credentials - such as avoiding buffered WRITEs
and COMMITs when the gss context will expire before the WRITEs are flushed
and COMMITs are sent.

These helper functions enable checking the expiration of an underlying
credential key for a generic rpc credential, e.g. the gss_cred gss context
gc_expiry which for Kerberos is set to the remaining TGT lifetime.

A new rpc_authops key_timeout is only defined for the generic auth.
A new rpc_credops crkey_to_expire is only defined for the generic cred.
A new rpc_credops crkey_timeout is only defined for the gss cred.

Set a credential key expiry watermark, RPC_KEY_EXPIRE_TIMEO set to 240 seconds
as a default and can be set via a module parameter as we need to ensure there
is time for any dirty data to be flushed.

If key_timeout is called on a credential with an underlying credential key that
will expire within watermark seconds, we set the RPC_CRED_KEY_EXPIRE_SOON
flag in the generic_cred acred so that the NFS layer can clean up prior to
key expiration.

Checking a generic credential's underlying credential involves a cred lookup.
To avoid this lookup in the normal case when the underlying credential has
a key that is valid (before the watermark), a notify flag is set in
the generic credential the first time the key_timeout is called. The
generic credential then stops checking the underlying credential key expiry, and
the underlying credential (gss_cred) match routine then checks the key
expiration upon each normal use and sets a flag in the associated generic
credential only when the key expiration is within the watermark.
This in turn signals the generic credential key_timeout to perform the extra
credential lookup thereafter.

Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

Showing 4 changed files with 169 additions and 2 deletions Inline Diff

include/linux/sunrpc/auth.h
1 /* 1 /*
2 * linux/include/linux/sunrpc/auth.h 2 * linux/include/linux/sunrpc/auth.h
3 * 3 *
4 * Declarations for the RPC client authentication machinery. 4 * Declarations for the RPC client authentication machinery.
5 * 5 *
6 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> 6 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
7 */ 7 */
8 8
9 #ifndef _LINUX_SUNRPC_AUTH_H 9 #ifndef _LINUX_SUNRPC_AUTH_H
10 #define _LINUX_SUNRPC_AUTH_H 10 #define _LINUX_SUNRPC_AUTH_H
11 11
12 #ifdef __KERNEL__ 12 #ifdef __KERNEL__
13 13
14 #include <linux/sunrpc/sched.h> 14 #include <linux/sunrpc/sched.h>
15 #include <linux/sunrpc/msg_prot.h> 15 #include <linux/sunrpc/msg_prot.h>
16 #include <linux/sunrpc/xdr.h> 16 #include <linux/sunrpc/xdr.h>
17 17
18 #include <linux/atomic.h> 18 #include <linux/atomic.h>
19 #include <linux/rcupdate.h> 19 #include <linux/rcupdate.h>
20 #include <linux/uidgid.h> 20 #include <linux/uidgid.h>
21 21
22 /* size of the nodename buffer */ 22 /* size of the nodename buffer */
23 #define UNX_MAXNODENAME 32 23 #define UNX_MAXNODENAME 32
24 24
25 struct rpcsec_gss_info; 25 struct rpcsec_gss_info;
26 26
27 /* auth_cred ac_flags bits */
28 enum {
29 RPC_CRED_NO_CRKEY_TIMEOUT = 0, /* underlying cred has no key timeout */
30 RPC_CRED_KEY_EXPIRE_SOON = 1, /* underlying cred key will expire soon */
31 RPC_CRED_NOTIFY_TIMEOUT = 2, /* nofity generic cred when underlying
32 key will expire soon */
33 };
34
27 /* Work around the lack of a VFS credential */ 35 /* Work around the lack of a VFS credential */
28 struct auth_cred { 36 struct auth_cred {
29 kuid_t uid; 37 kuid_t uid;
30 kgid_t gid; 38 kgid_t gid;
31 struct group_info *group_info; 39 struct group_info *group_info;
32 const char *principal; 40 const char *principal;
41 unsigned long ac_flags;
33 unsigned char machine_cred : 1; 42 unsigned char machine_cred : 1;
34 }; 43 };
35 44
36 /* 45 /*
37 * Client user credentials 46 * Client user credentials
38 */ 47 */
39 struct rpc_auth; 48 struct rpc_auth;
40 struct rpc_credops; 49 struct rpc_credops;
41 struct rpc_cred { 50 struct rpc_cred {
42 struct hlist_node cr_hash; /* hash chain */ 51 struct hlist_node cr_hash; /* hash chain */
43 struct list_head cr_lru; /* lru garbage collection */ 52 struct list_head cr_lru; /* lru garbage collection */
44 struct rcu_head cr_rcu; 53 struct rcu_head cr_rcu;
45 struct rpc_auth * cr_auth; 54 struct rpc_auth * cr_auth;
46 const struct rpc_credops *cr_ops; 55 const struct rpc_credops *cr_ops;
47 #ifdef RPC_DEBUG 56 #ifdef RPC_DEBUG
48 unsigned long cr_magic; /* 0x0f4aa4f0 */ 57 unsigned long cr_magic; /* 0x0f4aa4f0 */
49 #endif 58 #endif
50 unsigned long cr_expire; /* when to gc */ 59 unsigned long cr_expire; /* when to gc */
51 unsigned long cr_flags; /* various flags */ 60 unsigned long cr_flags; /* various flags */
52 atomic_t cr_count; /* ref count */ 61 atomic_t cr_count; /* ref count */
53 62
54 kuid_t cr_uid; 63 kuid_t cr_uid;
55 64
56 /* per-flavor data */ 65 /* per-flavor data */
57 }; 66 };
58 #define RPCAUTH_CRED_NEW 0 67 #define RPCAUTH_CRED_NEW 0
59 #define RPCAUTH_CRED_UPTODATE 1 68 #define RPCAUTH_CRED_UPTODATE 1
60 #define RPCAUTH_CRED_HASHED 2 69 #define RPCAUTH_CRED_HASHED 2
61 #define RPCAUTH_CRED_NEGATIVE 3 70 #define RPCAUTH_CRED_NEGATIVE 3
62 71
63 #define RPCAUTH_CRED_MAGIC 0x0f4aa4f0 72 #define RPCAUTH_CRED_MAGIC 0x0f4aa4f0
64 73
65 /* 74 /*
66 * Client authentication handle 75 * Client authentication handle
67 */ 76 */
68 struct rpc_cred_cache; 77 struct rpc_cred_cache;
69 struct rpc_authops; 78 struct rpc_authops;
70 struct rpc_auth { 79 struct rpc_auth {
71 unsigned int au_cslack; /* call cred size estimate */ 80 unsigned int au_cslack; /* call cred size estimate */
72 /* guess at number of u32's auth adds before 81 /* guess at number of u32's auth adds before
73 * reply data; normally the verifier size: */ 82 * reply data; normally the verifier size: */
74 unsigned int au_rslack; 83 unsigned int au_rslack;
75 /* for gss, used to calculate au_rslack: */ 84 /* for gss, used to calculate au_rslack: */
76 unsigned int au_verfsize; 85 unsigned int au_verfsize;
77 86
78 unsigned int au_flags; /* various flags */ 87 unsigned int au_flags; /* various flags */
79 const struct rpc_authops *au_ops; /* operations */ 88 const struct rpc_authops *au_ops; /* operations */
80 rpc_authflavor_t au_flavor; /* pseudoflavor (note may 89 rpc_authflavor_t au_flavor; /* pseudoflavor (note may
81 * differ from the flavor in 90 * differ from the flavor in
82 * au_ops->au_flavor in gss 91 * au_ops->au_flavor in gss
83 * case) */ 92 * case) */
84 atomic_t au_count; /* Reference counter */ 93 atomic_t au_count; /* Reference counter */
85 94
86 struct rpc_cred_cache * au_credcache; 95 struct rpc_cred_cache * au_credcache;
87 /* per-flavor data */ 96 /* per-flavor data */
88 }; 97 };
89 98
90 struct rpc_auth_create_args { 99 struct rpc_auth_create_args {
91 rpc_authflavor_t pseudoflavor; 100 rpc_authflavor_t pseudoflavor;
92 const char *target_name; 101 const char *target_name;
93 }; 102 };
94 103
95 /* Flags for rpcauth_lookupcred() */ 104 /* Flags for rpcauth_lookupcred() */
96 #define RPCAUTH_LOOKUP_NEW 0x01 /* Accept an uninitialised cred */ 105 #define RPCAUTH_LOOKUP_NEW 0x01 /* Accept an uninitialised cred */
97 106
98 /* 107 /*
99 * Client authentication ops 108 * Client authentication ops
100 */ 109 */
101 struct rpc_authops { 110 struct rpc_authops {
102 struct module *owner; 111 struct module *owner;
103 rpc_authflavor_t au_flavor; /* flavor (RPC_AUTH_*) */ 112 rpc_authflavor_t au_flavor; /* flavor (RPC_AUTH_*) */
104 char * au_name; 113 char * au_name;
105 struct rpc_auth * (*create)(struct rpc_auth_create_args *, struct rpc_clnt *); 114 struct rpc_auth * (*create)(struct rpc_auth_create_args *, struct rpc_clnt *);
106 void (*destroy)(struct rpc_auth *); 115 void (*destroy)(struct rpc_auth *);
107 116
108 struct rpc_cred * (*lookup_cred)(struct rpc_auth *, struct auth_cred *, int); 117 struct rpc_cred * (*lookup_cred)(struct rpc_auth *, struct auth_cred *, int);
109 struct rpc_cred * (*crcreate)(struct rpc_auth*, struct auth_cred *, int); 118 struct rpc_cred * (*crcreate)(struct rpc_auth*, struct auth_cred *, int);
110 int (*list_pseudoflavors)(rpc_authflavor_t *, int); 119 int (*list_pseudoflavors)(rpc_authflavor_t *, int);
111 rpc_authflavor_t (*info2flavor)(struct rpcsec_gss_info *); 120 rpc_authflavor_t (*info2flavor)(struct rpcsec_gss_info *);
112 int (*flavor2info)(rpc_authflavor_t, 121 int (*flavor2info)(rpc_authflavor_t,
113 struct rpcsec_gss_info *); 122 struct rpcsec_gss_info *);
123 int (*key_timeout)(struct rpc_auth *,
124 struct rpc_cred *);
114 }; 125 };
115 126
116 struct rpc_credops { 127 struct rpc_credops {
117 const char * cr_name; /* Name of the auth flavour */ 128 const char * cr_name; /* Name of the auth flavour */
118 int (*cr_init)(struct rpc_auth *, struct rpc_cred *); 129 int (*cr_init)(struct rpc_auth *, struct rpc_cred *);
119 void (*crdestroy)(struct rpc_cred *); 130 void (*crdestroy)(struct rpc_cred *);
120 131
121 int (*crmatch)(struct auth_cred *, struct rpc_cred *, int); 132 int (*crmatch)(struct auth_cred *, struct rpc_cred *, int);
122 struct rpc_cred * (*crbind)(struct rpc_task *, struct rpc_cred *, int); 133 struct rpc_cred * (*crbind)(struct rpc_task *, struct rpc_cred *, int);
123 __be32 * (*crmarshal)(struct rpc_task *, __be32 *); 134 __be32 * (*crmarshal)(struct rpc_task *, __be32 *);
124 int (*crrefresh)(struct rpc_task *); 135 int (*crrefresh)(struct rpc_task *);
125 __be32 * (*crvalidate)(struct rpc_task *, __be32 *); 136 __be32 * (*crvalidate)(struct rpc_task *, __be32 *);
126 int (*crwrap_req)(struct rpc_task *, kxdreproc_t, 137 int (*crwrap_req)(struct rpc_task *, kxdreproc_t,
127 void *, __be32 *, void *); 138 void *, __be32 *, void *);
128 int (*crunwrap_resp)(struct rpc_task *, kxdrdproc_t, 139 int (*crunwrap_resp)(struct rpc_task *, kxdrdproc_t,
129 void *, __be32 *, void *); 140 void *, __be32 *, void *);
141 int (*crkey_timeout)(struct rpc_cred *);
142 bool (*crkey_to_expire)(struct rpc_cred *);
130 }; 143 };
131 144
132 extern const struct rpc_authops authunix_ops; 145 extern const struct rpc_authops authunix_ops;
133 extern const struct rpc_authops authnull_ops; 146 extern const struct rpc_authops authnull_ops;
134 147
135 int __init rpc_init_authunix(void); 148 int __init rpc_init_authunix(void);
136 int __init rpc_init_generic_auth(void); 149 int __init rpc_init_generic_auth(void);
137 int __init rpcauth_init_module(void); 150 int __init rpcauth_init_module(void);
138 void rpcauth_remove_module(void); 151 void rpcauth_remove_module(void);
139 void rpc_destroy_generic_auth(void); 152 void rpc_destroy_generic_auth(void);
140 void rpc_destroy_authunix(void); 153 void rpc_destroy_authunix(void);
141 154
142 struct rpc_cred * rpc_lookup_cred(void); 155 struct rpc_cred * rpc_lookup_cred(void);
143 struct rpc_cred * rpc_lookup_machine_cred(const char *service_name); 156 struct rpc_cred * rpc_lookup_machine_cred(const char *service_name);
144 int rpcauth_register(const struct rpc_authops *); 157 int rpcauth_register(const struct rpc_authops *);
145 int rpcauth_unregister(const struct rpc_authops *); 158 int rpcauth_unregister(const struct rpc_authops *);
146 struct rpc_auth * rpcauth_create(struct rpc_auth_create_args *, 159 struct rpc_auth * rpcauth_create(struct rpc_auth_create_args *,
147 struct rpc_clnt *); 160 struct rpc_clnt *);
148 void rpcauth_release(struct rpc_auth *); 161 void rpcauth_release(struct rpc_auth *);
149 rpc_authflavor_t rpcauth_get_pseudoflavor(rpc_authflavor_t, 162 rpc_authflavor_t rpcauth_get_pseudoflavor(rpc_authflavor_t,
150 struct rpcsec_gss_info *); 163 struct rpcsec_gss_info *);
151 int rpcauth_get_gssinfo(rpc_authflavor_t, 164 int rpcauth_get_gssinfo(rpc_authflavor_t,
152 struct rpcsec_gss_info *); 165 struct rpcsec_gss_info *);
153 int rpcauth_list_flavors(rpc_authflavor_t *, int); 166 int rpcauth_list_flavors(rpc_authflavor_t *, int);
154 struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int); 167 struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int);
155 void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *); 168 void rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *);
156 struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int); 169 struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int);
157 struct rpc_cred * rpcauth_generic_bind_cred(struct rpc_task *, struct rpc_cred *, int); 170 struct rpc_cred * rpcauth_generic_bind_cred(struct rpc_task *, struct rpc_cred *, int);
158 void put_rpccred(struct rpc_cred *); 171 void put_rpccred(struct rpc_cred *);
159 __be32 * rpcauth_marshcred(struct rpc_task *, __be32 *); 172 __be32 * rpcauth_marshcred(struct rpc_task *, __be32 *);
160 __be32 * rpcauth_checkverf(struct rpc_task *, __be32 *); 173 __be32 * rpcauth_checkverf(struct rpc_task *, __be32 *);
161 int rpcauth_wrap_req(struct rpc_task *task, kxdreproc_t encode, void *rqstp, __be32 *data, void *obj); 174 int rpcauth_wrap_req(struct rpc_task *task, kxdreproc_t encode, void *rqstp, __be32 *data, void *obj);
162 int rpcauth_unwrap_resp(struct rpc_task *task, kxdrdproc_t decode, void *rqstp, __be32 *data, void *obj); 175 int rpcauth_unwrap_resp(struct rpc_task *task, kxdrdproc_t decode, void *rqstp, __be32 *data, void *obj);
163 int rpcauth_refreshcred(struct rpc_task *); 176 int rpcauth_refreshcred(struct rpc_task *);
164 void rpcauth_invalcred(struct rpc_task *); 177 void rpcauth_invalcred(struct rpc_task *);
165 int rpcauth_uptodatecred(struct rpc_task *); 178 int rpcauth_uptodatecred(struct rpc_task *);
166 int rpcauth_init_credcache(struct rpc_auth *); 179 int rpcauth_init_credcache(struct rpc_auth *);
167 void rpcauth_destroy_credcache(struct rpc_auth *); 180 void rpcauth_destroy_credcache(struct rpc_auth *);
168 void rpcauth_clear_credcache(struct rpc_cred_cache *); 181 void rpcauth_clear_credcache(struct rpc_cred_cache *);
182 int rpcauth_key_timeout_notify(struct rpc_auth *,
183 struct rpc_cred *);
184 bool rpcauth_cred_key_to_expire(struct rpc_cred *);
169 185
170 static inline 186 static inline
171 struct rpc_cred * get_rpccred(struct rpc_cred *cred) 187 struct rpc_cred * get_rpccred(struct rpc_cred *cred)
172 { 188 {
173 atomic_inc(&cred->cr_count); 189 atomic_inc(&cred->cr_count);
174 return cred; 190 return cred;
175 } 191 }
176 192
177 #endif /* __KERNEL__ */ 193 #endif /* __KERNEL__ */
178 #endif /* _LINUX_SUNRPC_AUTH_H */ 194 #endif /* _LINUX_SUNRPC_AUTH_H */
179 195
1 /* 1 /*
2 * linux/net/sunrpc/auth.c 2 * linux/net/sunrpc/auth.c
3 * 3 *
4 * Generic RPC client authentication API. 4 * Generic RPC client authentication API.
5 * 5 *
6 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> 6 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
7 */ 7 */
8 8
9 #include <linux/types.h> 9 #include <linux/types.h>
10 #include <linux/sched.h> 10 #include <linux/sched.h>
11 #include <linux/module.h> 11 #include <linux/module.h>
12 #include <linux/slab.h> 12 #include <linux/slab.h>
13 #include <linux/errno.h> 13 #include <linux/errno.h>
14 #include <linux/hash.h> 14 #include <linux/hash.h>
15 #include <linux/sunrpc/clnt.h> 15 #include <linux/sunrpc/clnt.h>
16 #include <linux/sunrpc/gss_api.h> 16 #include <linux/sunrpc/gss_api.h>
17 #include <linux/spinlock.h> 17 #include <linux/spinlock.h>
18 18
19 #ifdef RPC_DEBUG 19 #ifdef RPC_DEBUG
20 # define RPCDBG_FACILITY RPCDBG_AUTH 20 # define RPCDBG_FACILITY RPCDBG_AUTH
21 #endif 21 #endif
22 22
23 #define RPC_CREDCACHE_DEFAULT_HASHBITS (4) 23 #define RPC_CREDCACHE_DEFAULT_HASHBITS (4)
24 struct rpc_cred_cache { 24 struct rpc_cred_cache {
25 struct hlist_head *hashtable; 25 struct hlist_head *hashtable;
26 unsigned int hashbits; 26 unsigned int hashbits;
27 spinlock_t lock; 27 spinlock_t lock;
28 }; 28 };
29 29
30 static unsigned int auth_hashbits = RPC_CREDCACHE_DEFAULT_HASHBITS; 30 static unsigned int auth_hashbits = RPC_CREDCACHE_DEFAULT_HASHBITS;
31 31
32 static DEFINE_SPINLOCK(rpc_authflavor_lock); 32 static DEFINE_SPINLOCK(rpc_authflavor_lock);
33 static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = { 33 static const struct rpc_authops *auth_flavors[RPC_AUTH_MAXFLAVOR] = {
34 &authnull_ops, /* AUTH_NULL */ 34 &authnull_ops, /* AUTH_NULL */
35 &authunix_ops, /* AUTH_UNIX */ 35 &authunix_ops, /* AUTH_UNIX */
36 NULL, /* others can be loadable modules */ 36 NULL, /* others can be loadable modules */
37 }; 37 };
38 38
39 static LIST_HEAD(cred_unused); 39 static LIST_HEAD(cred_unused);
40 static unsigned long number_cred_unused; 40 static unsigned long number_cred_unused;
41 41
42 #define MAX_HASHTABLE_BITS (14) 42 #define MAX_HASHTABLE_BITS (14)
43 static int param_set_hashtbl_sz(const char *val, const struct kernel_param *kp) 43 static int param_set_hashtbl_sz(const char *val, const struct kernel_param *kp)
44 { 44 {
45 unsigned long num; 45 unsigned long num;
46 unsigned int nbits; 46 unsigned int nbits;
47 int ret; 47 int ret;
48 48
49 if (!val) 49 if (!val)
50 goto out_inval; 50 goto out_inval;
51 ret = strict_strtoul(val, 0, &num); 51 ret = strict_strtoul(val, 0, &num);
52 if (ret == -EINVAL) 52 if (ret == -EINVAL)
53 goto out_inval; 53 goto out_inval;
54 nbits = fls(num); 54 nbits = fls(num);
55 if (num > (1U << nbits)) 55 if (num > (1U << nbits))
56 nbits++; 56 nbits++;
57 if (nbits > MAX_HASHTABLE_BITS || nbits < 2) 57 if (nbits > MAX_HASHTABLE_BITS || nbits < 2)
58 goto out_inval; 58 goto out_inval;
59 *(unsigned int *)kp->arg = nbits; 59 *(unsigned int *)kp->arg = nbits;
60 return 0; 60 return 0;
61 out_inval: 61 out_inval:
62 return -EINVAL; 62 return -EINVAL;
63 } 63 }
64 64
65 static int param_get_hashtbl_sz(char *buffer, const struct kernel_param *kp) 65 static int param_get_hashtbl_sz(char *buffer, const struct kernel_param *kp)
66 { 66 {
67 unsigned int nbits; 67 unsigned int nbits;
68 68
69 nbits = *(unsigned int *)kp->arg; 69 nbits = *(unsigned int *)kp->arg;
70 return sprintf(buffer, "%u", 1U << nbits); 70 return sprintf(buffer, "%u", 1U << nbits);
71 } 71 }
72 72
73 #define param_check_hashtbl_sz(name, p) __param_check(name, p, unsigned int); 73 #define param_check_hashtbl_sz(name, p) __param_check(name, p, unsigned int);
74 74
75 static struct kernel_param_ops param_ops_hashtbl_sz = { 75 static struct kernel_param_ops param_ops_hashtbl_sz = {
76 .set = param_set_hashtbl_sz, 76 .set = param_set_hashtbl_sz,
77 .get = param_get_hashtbl_sz, 77 .get = param_get_hashtbl_sz,
78 }; 78 };
79 79
80 module_param_named(auth_hashtable_size, auth_hashbits, hashtbl_sz, 0644); 80 module_param_named(auth_hashtable_size, auth_hashbits, hashtbl_sz, 0644);
81 MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size"); 81 MODULE_PARM_DESC(auth_hashtable_size, "RPC credential cache hashtable size");
82 82
83 static u32 83 static u32
84 pseudoflavor_to_flavor(u32 flavor) { 84 pseudoflavor_to_flavor(u32 flavor) {
85 if (flavor > RPC_AUTH_MAXFLAVOR) 85 if (flavor > RPC_AUTH_MAXFLAVOR)
86 return RPC_AUTH_GSS; 86 return RPC_AUTH_GSS;
87 return flavor; 87 return flavor;
88 } 88 }
89 89
90 int 90 int
91 rpcauth_register(const struct rpc_authops *ops) 91 rpcauth_register(const struct rpc_authops *ops)
92 { 92 {
93 rpc_authflavor_t flavor; 93 rpc_authflavor_t flavor;
94 int ret = -EPERM; 94 int ret = -EPERM;
95 95
96 if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR) 96 if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR)
97 return -EINVAL; 97 return -EINVAL;
98 spin_lock(&rpc_authflavor_lock); 98 spin_lock(&rpc_authflavor_lock);
99 if (auth_flavors[flavor] == NULL) { 99 if (auth_flavors[flavor] == NULL) {
100 auth_flavors[flavor] = ops; 100 auth_flavors[flavor] = ops;
101 ret = 0; 101 ret = 0;
102 } 102 }
103 spin_unlock(&rpc_authflavor_lock); 103 spin_unlock(&rpc_authflavor_lock);
104 return ret; 104 return ret;
105 } 105 }
106 EXPORT_SYMBOL_GPL(rpcauth_register); 106 EXPORT_SYMBOL_GPL(rpcauth_register);
107 107
108 int 108 int
109 rpcauth_unregister(const struct rpc_authops *ops) 109 rpcauth_unregister(const struct rpc_authops *ops)
110 { 110 {
111 rpc_authflavor_t flavor; 111 rpc_authflavor_t flavor;
112 int ret = -EPERM; 112 int ret = -EPERM;
113 113
114 if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR) 114 if ((flavor = ops->au_flavor) >= RPC_AUTH_MAXFLAVOR)
115 return -EINVAL; 115 return -EINVAL;
116 spin_lock(&rpc_authflavor_lock); 116 spin_lock(&rpc_authflavor_lock);
117 if (auth_flavors[flavor] == ops) { 117 if (auth_flavors[flavor] == ops) {
118 auth_flavors[flavor] = NULL; 118 auth_flavors[flavor] = NULL;
119 ret = 0; 119 ret = 0;
120 } 120 }
121 spin_unlock(&rpc_authflavor_lock); 121 spin_unlock(&rpc_authflavor_lock);
122 return ret; 122 return ret;
123 } 123 }
124 EXPORT_SYMBOL_GPL(rpcauth_unregister); 124 EXPORT_SYMBOL_GPL(rpcauth_unregister);
125 125
126 /** 126 /**
127 * rpcauth_get_pseudoflavor - check if security flavor is supported 127 * rpcauth_get_pseudoflavor - check if security flavor is supported
128 * @flavor: a security flavor 128 * @flavor: a security flavor
129 * @info: a GSS mech OID, quality of protection, and service value 129 * @info: a GSS mech OID, quality of protection, and service value
130 * 130 *
131 * Verifies that an appropriate kernel module is available or already loaded. 131 * Verifies that an appropriate kernel module is available or already loaded.
132 * Returns an equivalent pseudoflavor, or RPC_AUTH_MAXFLAVOR if "flavor" is 132 * Returns an equivalent pseudoflavor, or RPC_AUTH_MAXFLAVOR if "flavor" is
133 * not supported locally. 133 * not supported locally.
134 */ 134 */
135 rpc_authflavor_t 135 rpc_authflavor_t
136 rpcauth_get_pseudoflavor(rpc_authflavor_t flavor, struct rpcsec_gss_info *info) 136 rpcauth_get_pseudoflavor(rpc_authflavor_t flavor, struct rpcsec_gss_info *info)
137 { 137 {
138 const struct rpc_authops *ops; 138 const struct rpc_authops *ops;
139 rpc_authflavor_t pseudoflavor; 139 rpc_authflavor_t pseudoflavor;
140 140
141 ops = auth_flavors[flavor]; 141 ops = auth_flavors[flavor];
142 if (ops == NULL) 142 if (ops == NULL)
143 request_module("rpc-auth-%u", flavor); 143 request_module("rpc-auth-%u", flavor);
144 spin_lock(&rpc_authflavor_lock); 144 spin_lock(&rpc_authflavor_lock);
145 ops = auth_flavors[flavor]; 145 ops = auth_flavors[flavor];
146 if (ops == NULL || !try_module_get(ops->owner)) { 146 if (ops == NULL || !try_module_get(ops->owner)) {
147 spin_unlock(&rpc_authflavor_lock); 147 spin_unlock(&rpc_authflavor_lock);
148 return RPC_AUTH_MAXFLAVOR; 148 return RPC_AUTH_MAXFLAVOR;
149 } 149 }
150 spin_unlock(&rpc_authflavor_lock); 150 spin_unlock(&rpc_authflavor_lock);
151 151
152 pseudoflavor = flavor; 152 pseudoflavor = flavor;
153 if (ops->info2flavor != NULL) 153 if (ops->info2flavor != NULL)
154 pseudoflavor = ops->info2flavor(info); 154 pseudoflavor = ops->info2flavor(info);
155 155
156 module_put(ops->owner); 156 module_put(ops->owner);
157 return pseudoflavor; 157 return pseudoflavor;
158 } 158 }
159 EXPORT_SYMBOL_GPL(rpcauth_get_pseudoflavor); 159 EXPORT_SYMBOL_GPL(rpcauth_get_pseudoflavor);
160 160
161 /** 161 /**
162 * rpcauth_get_gssinfo - find GSS tuple matching a GSS pseudoflavor 162 * rpcauth_get_gssinfo - find GSS tuple matching a GSS pseudoflavor
163 * @pseudoflavor: GSS pseudoflavor to match 163 * @pseudoflavor: GSS pseudoflavor to match
164 * @info: rpcsec_gss_info structure to fill in 164 * @info: rpcsec_gss_info structure to fill in
165 * 165 *
166 * Returns zero and fills in "info" if pseudoflavor matches a 166 * Returns zero and fills in "info" if pseudoflavor matches a
167 * supported mechanism. 167 * supported mechanism.
168 */ 168 */
169 int 169 int
170 rpcauth_get_gssinfo(rpc_authflavor_t pseudoflavor, struct rpcsec_gss_info *info) 170 rpcauth_get_gssinfo(rpc_authflavor_t pseudoflavor, struct rpcsec_gss_info *info)
171 { 171 {
172 rpc_authflavor_t flavor = pseudoflavor_to_flavor(pseudoflavor); 172 rpc_authflavor_t flavor = pseudoflavor_to_flavor(pseudoflavor);
173 const struct rpc_authops *ops; 173 const struct rpc_authops *ops;
174 int result; 174 int result;
175 175
176 if (flavor >= RPC_AUTH_MAXFLAVOR) 176 if (flavor >= RPC_AUTH_MAXFLAVOR)
177 return -EINVAL; 177 return -EINVAL;
178 178
179 ops = auth_flavors[flavor]; 179 ops = auth_flavors[flavor];
180 if (ops == NULL) 180 if (ops == NULL)
181 request_module("rpc-auth-%u", flavor); 181 request_module("rpc-auth-%u", flavor);
182 spin_lock(&rpc_authflavor_lock); 182 spin_lock(&rpc_authflavor_lock);
183 ops = auth_flavors[flavor]; 183 ops = auth_flavors[flavor];
184 if (ops == NULL || !try_module_get(ops->owner)) { 184 if (ops == NULL || !try_module_get(ops->owner)) {
185 spin_unlock(&rpc_authflavor_lock); 185 spin_unlock(&rpc_authflavor_lock);
186 return -ENOENT; 186 return -ENOENT;
187 } 187 }
188 spin_unlock(&rpc_authflavor_lock); 188 spin_unlock(&rpc_authflavor_lock);
189 189
190 result = -ENOENT; 190 result = -ENOENT;
191 if (ops->flavor2info != NULL) 191 if (ops->flavor2info != NULL)
192 result = ops->flavor2info(pseudoflavor, info); 192 result = ops->flavor2info(pseudoflavor, info);
193 193
194 module_put(ops->owner); 194 module_put(ops->owner);
195 return result; 195 return result;
196 } 196 }
197 EXPORT_SYMBOL_GPL(rpcauth_get_gssinfo); 197 EXPORT_SYMBOL_GPL(rpcauth_get_gssinfo);
198 198
199 /** 199 /**
200 * rpcauth_list_flavors - discover registered flavors and pseudoflavors 200 * rpcauth_list_flavors - discover registered flavors and pseudoflavors
201 * @array: array to fill in 201 * @array: array to fill in
202 * @size: size of "array" 202 * @size: size of "array"
203 * 203 *
204 * Returns the number of array items filled in, or a negative errno. 204 * Returns the number of array items filled in, or a negative errno.
205 * 205 *
206 * The returned array is not sorted by any policy. Callers should not 206 * The returned array is not sorted by any policy. Callers should not
207 * rely on the order of the items in the returned array. 207 * rely on the order of the items in the returned array.
208 */ 208 */
209 int 209 int
210 rpcauth_list_flavors(rpc_authflavor_t *array, int size) 210 rpcauth_list_flavors(rpc_authflavor_t *array, int size)
211 { 211 {
212 rpc_authflavor_t flavor; 212 rpc_authflavor_t flavor;
213 int result = 0; 213 int result = 0;
214 214
215 spin_lock(&rpc_authflavor_lock); 215 spin_lock(&rpc_authflavor_lock);
216 for (flavor = 0; flavor < RPC_AUTH_MAXFLAVOR; flavor++) { 216 for (flavor = 0; flavor < RPC_AUTH_MAXFLAVOR; flavor++) {
217 const struct rpc_authops *ops = auth_flavors[flavor]; 217 const struct rpc_authops *ops = auth_flavors[flavor];
218 rpc_authflavor_t pseudos[4]; 218 rpc_authflavor_t pseudos[4];
219 int i, len; 219 int i, len;
220 220
221 if (result >= size) { 221 if (result >= size) {
222 result = -ENOMEM; 222 result = -ENOMEM;
223 break; 223 break;
224 } 224 }
225 225
226 if (ops == NULL) 226 if (ops == NULL)
227 continue; 227 continue;
228 if (ops->list_pseudoflavors == NULL) { 228 if (ops->list_pseudoflavors == NULL) {
229 array[result++] = ops->au_flavor; 229 array[result++] = ops->au_flavor;
230 continue; 230 continue;
231 } 231 }
232 len = ops->list_pseudoflavors(pseudos, ARRAY_SIZE(pseudos)); 232 len = ops->list_pseudoflavors(pseudos, ARRAY_SIZE(pseudos));
233 if (len < 0) { 233 if (len < 0) {
234 result = len; 234 result = len;
235 break; 235 break;
236 } 236 }
237 for (i = 0; i < len; i++) { 237 for (i = 0; i < len; i++) {
238 if (result >= size) { 238 if (result >= size) {
239 result = -ENOMEM; 239 result = -ENOMEM;
240 break; 240 break;
241 } 241 }
242 array[result++] = pseudos[i]; 242 array[result++] = pseudos[i];
243 } 243 }
244 } 244 }
245 spin_unlock(&rpc_authflavor_lock); 245 spin_unlock(&rpc_authflavor_lock);
246 246
247 dprintk("RPC: %s returns %d\n", __func__, result); 247 dprintk("RPC: %s returns %d\n", __func__, result);
248 return result; 248 return result;
249 } 249 }
250 EXPORT_SYMBOL_GPL(rpcauth_list_flavors); 250 EXPORT_SYMBOL_GPL(rpcauth_list_flavors);
251 251
252 struct rpc_auth * 252 struct rpc_auth *
253 rpcauth_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt) 253 rpcauth_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
254 { 254 {
255 struct rpc_auth *auth; 255 struct rpc_auth *auth;
256 const struct rpc_authops *ops; 256 const struct rpc_authops *ops;
257 u32 flavor = pseudoflavor_to_flavor(args->pseudoflavor); 257 u32 flavor = pseudoflavor_to_flavor(args->pseudoflavor);
258 258
259 auth = ERR_PTR(-EINVAL); 259 auth = ERR_PTR(-EINVAL);
260 if (flavor >= RPC_AUTH_MAXFLAVOR) 260 if (flavor >= RPC_AUTH_MAXFLAVOR)
261 goto out; 261 goto out;
262 262
263 if ((ops = auth_flavors[flavor]) == NULL) 263 if ((ops = auth_flavors[flavor]) == NULL)
264 request_module("rpc-auth-%u", flavor); 264 request_module("rpc-auth-%u", flavor);
265 spin_lock(&rpc_authflavor_lock); 265 spin_lock(&rpc_authflavor_lock);
266 ops = auth_flavors[flavor]; 266 ops = auth_flavors[flavor];
267 if (ops == NULL || !try_module_get(ops->owner)) { 267 if (ops == NULL || !try_module_get(ops->owner)) {
268 spin_unlock(&rpc_authflavor_lock); 268 spin_unlock(&rpc_authflavor_lock);
269 goto out; 269 goto out;
270 } 270 }
271 spin_unlock(&rpc_authflavor_lock); 271 spin_unlock(&rpc_authflavor_lock);
272 auth = ops->create(args, clnt); 272 auth = ops->create(args, clnt);
273 module_put(ops->owner); 273 module_put(ops->owner);
274 if (IS_ERR(auth)) 274 if (IS_ERR(auth))
275 return auth; 275 return auth;
276 if (clnt->cl_auth) 276 if (clnt->cl_auth)
277 rpcauth_release(clnt->cl_auth); 277 rpcauth_release(clnt->cl_auth);
278 clnt->cl_auth = auth; 278 clnt->cl_auth = auth;
279 279
280 out: 280 out:
281 return auth; 281 return auth;
282 } 282 }
283 EXPORT_SYMBOL_GPL(rpcauth_create); 283 EXPORT_SYMBOL_GPL(rpcauth_create);
284 284
285 void 285 void
286 rpcauth_release(struct rpc_auth *auth) 286 rpcauth_release(struct rpc_auth *auth)
287 { 287 {
288 if (!atomic_dec_and_test(&auth->au_count)) 288 if (!atomic_dec_and_test(&auth->au_count))
289 return; 289 return;
290 auth->au_ops->destroy(auth); 290 auth->au_ops->destroy(auth);
291 } 291 }
292 292
293 static DEFINE_SPINLOCK(rpc_credcache_lock); 293 static DEFINE_SPINLOCK(rpc_credcache_lock);
294 294
295 static void 295 static void
296 rpcauth_unhash_cred_locked(struct rpc_cred *cred) 296 rpcauth_unhash_cred_locked(struct rpc_cred *cred)
297 { 297 {
298 hlist_del_rcu(&cred->cr_hash); 298 hlist_del_rcu(&cred->cr_hash);
299 smp_mb__before_clear_bit(); 299 smp_mb__before_clear_bit();
300 clear_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags); 300 clear_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags);
301 } 301 }
302 302
303 static int 303 static int
304 rpcauth_unhash_cred(struct rpc_cred *cred) 304 rpcauth_unhash_cred(struct rpc_cred *cred)
305 { 305 {
306 spinlock_t *cache_lock; 306 spinlock_t *cache_lock;
307 int ret; 307 int ret;
308 308
309 cache_lock = &cred->cr_auth->au_credcache->lock; 309 cache_lock = &cred->cr_auth->au_credcache->lock;
310 spin_lock(cache_lock); 310 spin_lock(cache_lock);
311 ret = atomic_read(&cred->cr_count) == 0; 311 ret = atomic_read(&cred->cr_count) == 0;
312 if (ret) 312 if (ret)
313 rpcauth_unhash_cred_locked(cred); 313 rpcauth_unhash_cred_locked(cred);
314 spin_unlock(cache_lock); 314 spin_unlock(cache_lock);
315 return ret; 315 return ret;
316 } 316 }
317 317
318 /* 318 /*
319 * Initialize RPC credential cache 319 * Initialize RPC credential cache
320 */ 320 */
321 int 321 int
322 rpcauth_init_credcache(struct rpc_auth *auth) 322 rpcauth_init_credcache(struct rpc_auth *auth)
323 { 323 {
324 struct rpc_cred_cache *new; 324 struct rpc_cred_cache *new;
325 unsigned int hashsize; 325 unsigned int hashsize;
326 326
327 new = kmalloc(sizeof(*new), GFP_KERNEL); 327 new = kmalloc(sizeof(*new), GFP_KERNEL);
328 if (!new) 328 if (!new)
329 goto out_nocache; 329 goto out_nocache;
330 new->hashbits = auth_hashbits; 330 new->hashbits = auth_hashbits;
331 hashsize = 1U << new->hashbits; 331 hashsize = 1U << new->hashbits;
332 new->hashtable = kcalloc(hashsize, sizeof(new->hashtable[0]), GFP_KERNEL); 332 new->hashtable = kcalloc(hashsize, sizeof(new->hashtable[0]), GFP_KERNEL);
333 if (!new->hashtable) 333 if (!new->hashtable)
334 goto out_nohashtbl; 334 goto out_nohashtbl;
335 spin_lock_init(&new->lock); 335 spin_lock_init(&new->lock);
336 auth->au_credcache = new; 336 auth->au_credcache = new;
337 return 0; 337 return 0;
338 out_nohashtbl: 338 out_nohashtbl:
339 kfree(new); 339 kfree(new);
340 out_nocache: 340 out_nocache:
341 return -ENOMEM; 341 return -ENOMEM;
342 } 342 }
343 EXPORT_SYMBOL_GPL(rpcauth_init_credcache); 343 EXPORT_SYMBOL_GPL(rpcauth_init_credcache);
344 344
345 /* 345 /*
346 * Setup a credential key lifetime timeout notification
347 */
348 int
349 rpcauth_key_timeout_notify(struct rpc_auth *auth, struct rpc_cred *cred)
350 {
351 if (!cred->cr_auth->au_ops->key_timeout)
352 return 0;
353 return cred->cr_auth->au_ops->key_timeout(auth, cred);
354 }
355 EXPORT_SYMBOL_GPL(rpcauth_key_timeout_notify);
356
357 bool
358 rpcauth_cred_key_to_expire(struct rpc_cred *cred)
359 {
360 if (!cred->cr_ops->crkey_to_expire)
361 return false;
362 return cred->cr_ops->crkey_to_expire(cred);
363 }
364 EXPORT_SYMBOL_GPL(rpcauth_cred_key_to_expire);
365
366 /*
346 * Destroy a list of credentials 367 * Destroy a list of credentials
347 */ 368 */
348 static inline 369 static inline
349 void rpcauth_destroy_credlist(struct list_head *head) 370 void rpcauth_destroy_credlist(struct list_head *head)
350 { 371 {
351 struct rpc_cred *cred; 372 struct rpc_cred *cred;
352 373
353 while (!list_empty(head)) { 374 while (!list_empty(head)) {
354 cred = list_entry(head->next, struct rpc_cred, cr_lru); 375 cred = list_entry(head->next, struct rpc_cred, cr_lru);
355 list_del_init(&cred->cr_lru); 376 list_del_init(&cred->cr_lru);
356 put_rpccred(cred); 377 put_rpccred(cred);
357 } 378 }
358 } 379 }
359 380
360 /* 381 /*
361 * Clear the RPC credential cache, and delete those credentials 382 * Clear the RPC credential cache, and delete those credentials
362 * that are not referenced. 383 * that are not referenced.
363 */ 384 */
364 void 385 void
365 rpcauth_clear_credcache(struct rpc_cred_cache *cache) 386 rpcauth_clear_credcache(struct rpc_cred_cache *cache)
366 { 387 {
367 LIST_HEAD(free); 388 LIST_HEAD(free);
368 struct hlist_head *head; 389 struct hlist_head *head;
369 struct rpc_cred *cred; 390 struct rpc_cred *cred;
370 unsigned int hashsize = 1U << cache->hashbits; 391 unsigned int hashsize = 1U << cache->hashbits;
371 int i; 392 int i;
372 393
373 spin_lock(&rpc_credcache_lock); 394 spin_lock(&rpc_credcache_lock);
374 spin_lock(&cache->lock); 395 spin_lock(&cache->lock);
375 for (i = 0; i < hashsize; i++) { 396 for (i = 0; i < hashsize; i++) {
376 head = &cache->hashtable[i]; 397 head = &cache->hashtable[i];
377 while (!hlist_empty(head)) { 398 while (!hlist_empty(head)) {
378 cred = hlist_entry(head->first, struct rpc_cred, cr_hash); 399 cred = hlist_entry(head->first, struct rpc_cred, cr_hash);
379 get_rpccred(cred); 400 get_rpccred(cred);
380 if (!list_empty(&cred->cr_lru)) { 401 if (!list_empty(&cred->cr_lru)) {
381 list_del(&cred->cr_lru); 402 list_del(&cred->cr_lru);
382 number_cred_unused--; 403 number_cred_unused--;
383 } 404 }
384 list_add_tail(&cred->cr_lru, &free); 405 list_add_tail(&cred->cr_lru, &free);
385 rpcauth_unhash_cred_locked(cred); 406 rpcauth_unhash_cred_locked(cred);
386 } 407 }
387 } 408 }
388 spin_unlock(&cache->lock); 409 spin_unlock(&cache->lock);
389 spin_unlock(&rpc_credcache_lock); 410 spin_unlock(&rpc_credcache_lock);
390 rpcauth_destroy_credlist(&free); 411 rpcauth_destroy_credlist(&free);
391 } 412 }
392 413
393 /* 414 /*
394 * Destroy the RPC credential cache 415 * Destroy the RPC credential cache
395 */ 416 */
396 void 417 void
397 rpcauth_destroy_credcache(struct rpc_auth *auth) 418 rpcauth_destroy_credcache(struct rpc_auth *auth)
398 { 419 {
399 struct rpc_cred_cache *cache = auth->au_credcache; 420 struct rpc_cred_cache *cache = auth->au_credcache;
400 421
401 if (cache) { 422 if (cache) {
402 auth->au_credcache = NULL; 423 auth->au_credcache = NULL;
403 rpcauth_clear_credcache(cache); 424 rpcauth_clear_credcache(cache);
404 kfree(cache->hashtable); 425 kfree(cache->hashtable);
405 kfree(cache); 426 kfree(cache);
406 } 427 }
407 } 428 }
408 EXPORT_SYMBOL_GPL(rpcauth_destroy_credcache); 429 EXPORT_SYMBOL_GPL(rpcauth_destroy_credcache);
409 430
410 431
411 #define RPC_AUTH_EXPIRY_MORATORIUM (60 * HZ) 432 #define RPC_AUTH_EXPIRY_MORATORIUM (60 * HZ)
412 433
413 /* 434 /*
414 * Remove stale credentials. Avoid sleeping inside the loop. 435 * Remove stale credentials. Avoid sleeping inside the loop.
415 */ 436 */
416 static int 437 static int
417 rpcauth_prune_expired(struct list_head *free, int nr_to_scan) 438 rpcauth_prune_expired(struct list_head *free, int nr_to_scan)
418 { 439 {
419 spinlock_t *cache_lock; 440 spinlock_t *cache_lock;
420 struct rpc_cred *cred, *next; 441 struct rpc_cred *cred, *next;
421 unsigned long expired = jiffies - RPC_AUTH_EXPIRY_MORATORIUM; 442 unsigned long expired = jiffies - RPC_AUTH_EXPIRY_MORATORIUM;
422 443
423 list_for_each_entry_safe(cred, next, &cred_unused, cr_lru) { 444 list_for_each_entry_safe(cred, next, &cred_unused, cr_lru) {
424 445
425 if (nr_to_scan-- == 0) 446 if (nr_to_scan-- == 0)
426 break; 447 break;
427 /* 448 /*
428 * Enforce a 60 second garbage collection moratorium 449 * Enforce a 60 second garbage collection moratorium
429 * Note that the cred_unused list must be time-ordered. 450 * Note that the cred_unused list must be time-ordered.
430 */ 451 */
431 if (time_in_range(cred->cr_expire, expired, jiffies) && 452 if (time_in_range(cred->cr_expire, expired, jiffies) &&
432 test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) 453 test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0)
433 return 0; 454 return 0;
434 455
435 list_del_init(&cred->cr_lru); 456 list_del_init(&cred->cr_lru);
436 number_cred_unused--; 457 number_cred_unused--;
437 if (atomic_read(&cred->cr_count) != 0) 458 if (atomic_read(&cred->cr_count) != 0)
438 continue; 459 continue;
439 460
440 cache_lock = &cred->cr_auth->au_credcache->lock; 461 cache_lock = &cred->cr_auth->au_credcache->lock;
441 spin_lock(cache_lock); 462 spin_lock(cache_lock);
442 if (atomic_read(&cred->cr_count) == 0) { 463 if (atomic_read(&cred->cr_count) == 0) {
443 get_rpccred(cred); 464 get_rpccred(cred);
444 list_add_tail(&cred->cr_lru, free); 465 list_add_tail(&cred->cr_lru, free);
445 rpcauth_unhash_cred_locked(cred); 466 rpcauth_unhash_cred_locked(cred);
446 } 467 }
447 spin_unlock(cache_lock); 468 spin_unlock(cache_lock);
448 } 469 }
449 return (number_cred_unused / 100) * sysctl_vfs_cache_pressure; 470 return (number_cred_unused / 100) * sysctl_vfs_cache_pressure;
450 } 471 }
451 472
452 /* 473 /*
453 * Run memory cache shrinker. 474 * Run memory cache shrinker.
454 */ 475 */
455 static int 476 static int
456 rpcauth_cache_shrinker(struct shrinker *shrink, struct shrink_control *sc) 477 rpcauth_cache_shrinker(struct shrinker *shrink, struct shrink_control *sc)
457 { 478 {
458 LIST_HEAD(free); 479 LIST_HEAD(free);
459 int res; 480 int res;
460 int nr_to_scan = sc->nr_to_scan; 481 int nr_to_scan = sc->nr_to_scan;
461 gfp_t gfp_mask = sc->gfp_mask; 482 gfp_t gfp_mask = sc->gfp_mask;
462 483
463 if ((gfp_mask & GFP_KERNEL) != GFP_KERNEL) 484 if ((gfp_mask & GFP_KERNEL) != GFP_KERNEL)
464 return (nr_to_scan == 0) ? 0 : -1; 485 return (nr_to_scan == 0) ? 0 : -1;
465 if (list_empty(&cred_unused)) 486 if (list_empty(&cred_unused))
466 return 0; 487 return 0;
467 spin_lock(&rpc_credcache_lock); 488 spin_lock(&rpc_credcache_lock);
468 res = rpcauth_prune_expired(&free, nr_to_scan); 489 res = rpcauth_prune_expired(&free, nr_to_scan);
469 spin_unlock(&rpc_credcache_lock); 490 spin_unlock(&rpc_credcache_lock);
470 rpcauth_destroy_credlist(&free); 491 rpcauth_destroy_credlist(&free);
471 return res; 492 return res;
472 } 493 }
473 494
474 /* 495 /*
475 * Look up a process' credentials in the authentication cache 496 * Look up a process' credentials in the authentication cache
476 */ 497 */
477 struct rpc_cred * 498 struct rpc_cred *
478 rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred, 499 rpcauth_lookup_credcache(struct rpc_auth *auth, struct auth_cred * acred,
479 int flags) 500 int flags)
480 { 501 {
481 LIST_HEAD(free); 502 LIST_HEAD(free);
482 struct rpc_cred_cache *cache = auth->au_credcache; 503 struct rpc_cred_cache *cache = auth->au_credcache;
483 struct rpc_cred *cred = NULL, 504 struct rpc_cred *cred = NULL,
484 *entry, *new; 505 *entry, *new;
485 unsigned int nr; 506 unsigned int nr;
486 507
487 nr = hash_long(from_kuid(&init_user_ns, acred->uid), cache->hashbits); 508 nr = hash_long(from_kuid(&init_user_ns, acred->uid), cache->hashbits);
488 509
489 rcu_read_lock(); 510 rcu_read_lock();
490 hlist_for_each_entry_rcu(entry, &cache->hashtable[nr], cr_hash) { 511 hlist_for_each_entry_rcu(entry, &cache->hashtable[nr], cr_hash) {
491 if (!entry->cr_ops->crmatch(acred, entry, flags)) 512 if (!entry->cr_ops->crmatch(acred, entry, flags))
492 continue; 513 continue;
493 spin_lock(&cache->lock); 514 spin_lock(&cache->lock);
494 if (test_bit(RPCAUTH_CRED_HASHED, &entry->cr_flags) == 0) { 515 if (test_bit(RPCAUTH_CRED_HASHED, &entry->cr_flags) == 0) {
495 spin_unlock(&cache->lock); 516 spin_unlock(&cache->lock);
496 continue; 517 continue;
497 } 518 }
498 cred = get_rpccred(entry); 519 cred = get_rpccred(entry);
499 spin_unlock(&cache->lock); 520 spin_unlock(&cache->lock);
500 break; 521 break;
501 } 522 }
502 rcu_read_unlock(); 523 rcu_read_unlock();
503 524
504 if (cred != NULL) 525 if (cred != NULL)
505 goto found; 526 goto found;
506 527
507 new = auth->au_ops->crcreate(auth, acred, flags); 528 new = auth->au_ops->crcreate(auth, acred, flags);
508 if (IS_ERR(new)) { 529 if (IS_ERR(new)) {
509 cred = new; 530 cred = new;
510 goto out; 531 goto out;
511 } 532 }
512 533
513 spin_lock(&cache->lock); 534 spin_lock(&cache->lock);
514 hlist_for_each_entry(entry, &cache->hashtable[nr], cr_hash) { 535 hlist_for_each_entry(entry, &cache->hashtable[nr], cr_hash) {
515 if (!entry->cr_ops->crmatch(acred, entry, flags)) 536 if (!entry->cr_ops->crmatch(acred, entry, flags))
516 continue; 537 continue;
517 cred = get_rpccred(entry); 538 cred = get_rpccred(entry);
518 break; 539 break;
519 } 540 }
520 if (cred == NULL) { 541 if (cred == NULL) {
521 cred = new; 542 cred = new;
522 set_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags); 543 set_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags);
523 hlist_add_head_rcu(&cred->cr_hash, &cache->hashtable[nr]); 544 hlist_add_head_rcu(&cred->cr_hash, &cache->hashtable[nr]);
524 } else 545 } else
525 list_add_tail(&new->cr_lru, &free); 546 list_add_tail(&new->cr_lru, &free);
526 spin_unlock(&cache->lock); 547 spin_unlock(&cache->lock);
527 found: 548 found:
528 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) && 549 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) &&
529 cred->cr_ops->cr_init != NULL && 550 cred->cr_ops->cr_init != NULL &&
530 !(flags & RPCAUTH_LOOKUP_NEW)) { 551 !(flags & RPCAUTH_LOOKUP_NEW)) {
531 int res = cred->cr_ops->cr_init(auth, cred); 552 int res = cred->cr_ops->cr_init(auth, cred);
532 if (res < 0) { 553 if (res < 0) {
533 put_rpccred(cred); 554 put_rpccred(cred);
534 cred = ERR_PTR(res); 555 cred = ERR_PTR(res);
535 } 556 }
536 } 557 }
537 rpcauth_destroy_credlist(&free); 558 rpcauth_destroy_credlist(&free);
538 out: 559 out:
539 return cred; 560 return cred;
540 } 561 }
541 EXPORT_SYMBOL_GPL(rpcauth_lookup_credcache); 562 EXPORT_SYMBOL_GPL(rpcauth_lookup_credcache);
542 563
543 struct rpc_cred * 564 struct rpc_cred *
544 rpcauth_lookupcred(struct rpc_auth *auth, int flags) 565 rpcauth_lookupcred(struct rpc_auth *auth, int flags)
545 { 566 {
546 struct auth_cred acred; 567 struct auth_cred acred;
547 struct rpc_cred *ret; 568 struct rpc_cred *ret;
548 const struct cred *cred = current_cred(); 569 const struct cred *cred = current_cred();
549 570
550 dprintk("RPC: looking up %s cred\n", 571 dprintk("RPC: looking up %s cred\n",
551 auth->au_ops->au_name); 572 auth->au_ops->au_name);
552 573
553 memset(&acred, 0, sizeof(acred)); 574 memset(&acred, 0, sizeof(acred));
554 acred.uid = cred->fsuid; 575 acred.uid = cred->fsuid;
555 acred.gid = cred->fsgid; 576 acred.gid = cred->fsgid;
556 acred.group_info = get_group_info(((struct cred *)cred)->group_info); 577 acred.group_info = get_group_info(((struct cred *)cred)->group_info);
557 578
558 ret = auth->au_ops->lookup_cred(auth, &acred, flags); 579 ret = auth->au_ops->lookup_cred(auth, &acred, flags);
559 put_group_info(acred.group_info); 580 put_group_info(acred.group_info);
560 return ret; 581 return ret;
561 } 582 }
562 583
563 void 584 void
564 rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred, 585 rpcauth_init_cred(struct rpc_cred *cred, const struct auth_cred *acred,
565 struct rpc_auth *auth, const struct rpc_credops *ops) 586 struct rpc_auth *auth, const struct rpc_credops *ops)
566 { 587 {
567 INIT_HLIST_NODE(&cred->cr_hash); 588 INIT_HLIST_NODE(&cred->cr_hash);
568 INIT_LIST_HEAD(&cred->cr_lru); 589 INIT_LIST_HEAD(&cred->cr_lru);
569 atomic_set(&cred->cr_count, 1); 590 atomic_set(&cred->cr_count, 1);
570 cred->cr_auth = auth; 591 cred->cr_auth = auth;
571 cred->cr_ops = ops; 592 cred->cr_ops = ops;
572 cred->cr_expire = jiffies; 593 cred->cr_expire = jiffies;
573 #ifdef RPC_DEBUG 594 #ifdef RPC_DEBUG
574 cred->cr_magic = RPCAUTH_CRED_MAGIC; 595 cred->cr_magic = RPCAUTH_CRED_MAGIC;
575 #endif 596 #endif
576 cred->cr_uid = acred->uid; 597 cred->cr_uid = acred->uid;
577 } 598 }
578 EXPORT_SYMBOL_GPL(rpcauth_init_cred); 599 EXPORT_SYMBOL_GPL(rpcauth_init_cred);
579 600
580 struct rpc_cred * 601 struct rpc_cred *
581 rpcauth_generic_bind_cred(struct rpc_task *task, struct rpc_cred *cred, int lookupflags) 602 rpcauth_generic_bind_cred(struct rpc_task *task, struct rpc_cred *cred, int lookupflags)
582 { 603 {
583 dprintk("RPC: %5u holding %s cred %p\n", task->tk_pid, 604 dprintk("RPC: %5u holding %s cred %p\n", task->tk_pid,
584 cred->cr_auth->au_ops->au_name, cred); 605 cred->cr_auth->au_ops->au_name, cred);
585 return get_rpccred(cred); 606 return get_rpccred(cred);
586 } 607 }
587 EXPORT_SYMBOL_GPL(rpcauth_generic_bind_cred); 608 EXPORT_SYMBOL_GPL(rpcauth_generic_bind_cred);
588 609
589 static struct rpc_cred * 610 static struct rpc_cred *
590 rpcauth_bind_root_cred(struct rpc_task *task, int lookupflags) 611 rpcauth_bind_root_cred(struct rpc_task *task, int lookupflags)
591 { 612 {
592 struct rpc_auth *auth = task->tk_client->cl_auth; 613 struct rpc_auth *auth = task->tk_client->cl_auth;
593 struct auth_cred acred = { 614 struct auth_cred acred = {
594 .uid = GLOBAL_ROOT_UID, 615 .uid = GLOBAL_ROOT_UID,
595 .gid = GLOBAL_ROOT_GID, 616 .gid = GLOBAL_ROOT_GID,
596 }; 617 };
597 618
598 dprintk("RPC: %5u looking up %s cred\n", 619 dprintk("RPC: %5u looking up %s cred\n",
599 task->tk_pid, task->tk_client->cl_auth->au_ops->au_name); 620 task->tk_pid, task->tk_client->cl_auth->au_ops->au_name);
600 return auth->au_ops->lookup_cred(auth, &acred, lookupflags); 621 return auth->au_ops->lookup_cred(auth, &acred, lookupflags);
601 } 622 }
602 623
603 static struct rpc_cred * 624 static struct rpc_cred *
604 rpcauth_bind_new_cred(struct rpc_task *task, int lookupflags) 625 rpcauth_bind_new_cred(struct rpc_task *task, int lookupflags)
605 { 626 {
606 struct rpc_auth *auth = task->tk_client->cl_auth; 627 struct rpc_auth *auth = task->tk_client->cl_auth;
607 628
608 dprintk("RPC: %5u looking up %s cred\n", 629 dprintk("RPC: %5u looking up %s cred\n",
609 task->tk_pid, auth->au_ops->au_name); 630 task->tk_pid, auth->au_ops->au_name);
610 return rpcauth_lookupcred(auth, lookupflags); 631 return rpcauth_lookupcred(auth, lookupflags);
611 } 632 }
612 633
613 static int 634 static int
614 rpcauth_bindcred(struct rpc_task *task, struct rpc_cred *cred, int flags) 635 rpcauth_bindcred(struct rpc_task *task, struct rpc_cred *cred, int flags)
615 { 636 {
616 struct rpc_rqst *req = task->tk_rqstp; 637 struct rpc_rqst *req = task->tk_rqstp;
617 struct rpc_cred *new; 638 struct rpc_cred *new;
618 int lookupflags = 0; 639 int lookupflags = 0;
619 640
620 if (flags & RPC_TASK_ASYNC) 641 if (flags & RPC_TASK_ASYNC)
621 lookupflags |= RPCAUTH_LOOKUP_NEW; 642 lookupflags |= RPCAUTH_LOOKUP_NEW;
622 if (cred != NULL) 643 if (cred != NULL)
623 new = cred->cr_ops->crbind(task, cred, lookupflags); 644 new = cred->cr_ops->crbind(task, cred, lookupflags);
624 else if (flags & RPC_TASK_ROOTCREDS) 645 else if (flags & RPC_TASK_ROOTCREDS)
625 new = rpcauth_bind_root_cred(task, lookupflags); 646 new = rpcauth_bind_root_cred(task, lookupflags);
626 else 647 else
627 new = rpcauth_bind_new_cred(task, lookupflags); 648 new = rpcauth_bind_new_cred(task, lookupflags);
628 if (IS_ERR(new)) 649 if (IS_ERR(new))
629 return PTR_ERR(new); 650 return PTR_ERR(new);
630 if (req->rq_cred != NULL) 651 if (req->rq_cred != NULL)
631 put_rpccred(req->rq_cred); 652 put_rpccred(req->rq_cred);
632 req->rq_cred = new; 653 req->rq_cred = new;
633 return 0; 654 return 0;
634 } 655 }
635 656
636 void 657 void
637 put_rpccred(struct rpc_cred *cred) 658 put_rpccred(struct rpc_cred *cred)
638 { 659 {
639 /* Fast path for unhashed credentials */ 660 /* Fast path for unhashed credentials */
640 if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) == 0) { 661 if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) == 0) {
641 if (atomic_dec_and_test(&cred->cr_count)) 662 if (atomic_dec_and_test(&cred->cr_count))
642 cred->cr_ops->crdestroy(cred); 663 cred->cr_ops->crdestroy(cred);
643 return; 664 return;
644 } 665 }
645 666
646 if (!atomic_dec_and_lock(&cred->cr_count, &rpc_credcache_lock)) 667 if (!atomic_dec_and_lock(&cred->cr_count, &rpc_credcache_lock))
647 return; 668 return;
648 if (!list_empty(&cred->cr_lru)) { 669 if (!list_empty(&cred->cr_lru)) {
649 number_cred_unused--; 670 number_cred_unused--;
650 list_del_init(&cred->cr_lru); 671 list_del_init(&cred->cr_lru);
651 } 672 }
652 if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) { 673 if (test_bit(RPCAUTH_CRED_HASHED, &cred->cr_flags) != 0) {
653 if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0) { 674 if (test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0) {
654 cred->cr_expire = jiffies; 675 cred->cr_expire = jiffies;
655 list_add_tail(&cred->cr_lru, &cred_unused); 676 list_add_tail(&cred->cr_lru, &cred_unused);
656 number_cred_unused++; 677 number_cred_unused++;
657 goto out_nodestroy; 678 goto out_nodestroy;
658 } 679 }
659 if (!rpcauth_unhash_cred(cred)) { 680 if (!rpcauth_unhash_cred(cred)) {
660 /* We were hashed and someone looked us up... */ 681 /* We were hashed and someone looked us up... */
661 goto out_nodestroy; 682 goto out_nodestroy;
662 } 683 }
663 } 684 }
664 spin_unlock(&rpc_credcache_lock); 685 spin_unlock(&rpc_credcache_lock);
665 cred->cr_ops->crdestroy(cred); 686 cred->cr_ops->crdestroy(cred);
666 return; 687 return;
667 out_nodestroy: 688 out_nodestroy:
668 spin_unlock(&rpc_credcache_lock); 689 spin_unlock(&rpc_credcache_lock);
669 } 690 }
670 EXPORT_SYMBOL_GPL(put_rpccred); 691 EXPORT_SYMBOL_GPL(put_rpccred);
671 692
672 __be32 * 693 __be32 *
673 rpcauth_marshcred(struct rpc_task *task, __be32 *p) 694 rpcauth_marshcred(struct rpc_task *task, __be32 *p)
674 { 695 {
675 struct rpc_cred *cred = task->tk_rqstp->rq_cred; 696 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
676 697
677 dprintk("RPC: %5u marshaling %s cred %p\n", 698 dprintk("RPC: %5u marshaling %s cred %p\n",
678 task->tk_pid, cred->cr_auth->au_ops->au_name, cred); 699 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
679 700
680 return cred->cr_ops->crmarshal(task, p); 701 return cred->cr_ops->crmarshal(task, p);
681 } 702 }
682 703
683 __be32 * 704 __be32 *
684 rpcauth_checkverf(struct rpc_task *task, __be32 *p) 705 rpcauth_checkverf(struct rpc_task *task, __be32 *p)
685 { 706 {
686 struct rpc_cred *cred = task->tk_rqstp->rq_cred; 707 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
687 708
688 dprintk("RPC: %5u validating %s cred %p\n", 709 dprintk("RPC: %5u validating %s cred %p\n",
689 task->tk_pid, cred->cr_auth->au_ops->au_name, cred); 710 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
690 711
691 return cred->cr_ops->crvalidate(task, p); 712 return cred->cr_ops->crvalidate(task, p);
692 } 713 }
693 714
694 static void rpcauth_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp, 715 static void rpcauth_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp,
695 __be32 *data, void *obj) 716 __be32 *data, void *obj)
696 { 717 {
697 struct xdr_stream xdr; 718 struct xdr_stream xdr;
698 719
699 xdr_init_encode(&xdr, &rqstp->rq_snd_buf, data); 720 xdr_init_encode(&xdr, &rqstp->rq_snd_buf, data);
700 encode(rqstp, &xdr, obj); 721 encode(rqstp, &xdr, obj);
701 } 722 }
702 723
703 int 724 int
704 rpcauth_wrap_req(struct rpc_task *task, kxdreproc_t encode, void *rqstp, 725 rpcauth_wrap_req(struct rpc_task *task, kxdreproc_t encode, void *rqstp,
705 __be32 *data, void *obj) 726 __be32 *data, void *obj)
706 { 727 {
707 struct rpc_cred *cred = task->tk_rqstp->rq_cred; 728 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
708 729
709 dprintk("RPC: %5u using %s cred %p to wrap rpc data\n", 730 dprintk("RPC: %5u using %s cred %p to wrap rpc data\n",
710 task->tk_pid, cred->cr_ops->cr_name, cred); 731 task->tk_pid, cred->cr_ops->cr_name, cred);
711 if (cred->cr_ops->crwrap_req) 732 if (cred->cr_ops->crwrap_req)
712 return cred->cr_ops->crwrap_req(task, encode, rqstp, data, obj); 733 return cred->cr_ops->crwrap_req(task, encode, rqstp, data, obj);
713 /* By default, we encode the arguments normally. */ 734 /* By default, we encode the arguments normally. */
714 rpcauth_wrap_req_encode(encode, rqstp, data, obj); 735 rpcauth_wrap_req_encode(encode, rqstp, data, obj);
715 return 0; 736 return 0;
716 } 737 }
717 738
718 static int 739 static int
719 rpcauth_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp, 740 rpcauth_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp,
720 __be32 *data, void *obj) 741 __be32 *data, void *obj)
721 { 742 {
722 struct xdr_stream xdr; 743 struct xdr_stream xdr;
723 744
724 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, data); 745 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, data);
725 return decode(rqstp, &xdr, obj); 746 return decode(rqstp, &xdr, obj);
726 } 747 }
727 748
728 int 749 int
729 rpcauth_unwrap_resp(struct rpc_task *task, kxdrdproc_t decode, void *rqstp, 750 rpcauth_unwrap_resp(struct rpc_task *task, kxdrdproc_t decode, void *rqstp,
730 __be32 *data, void *obj) 751 __be32 *data, void *obj)
731 { 752 {
732 struct rpc_cred *cred = task->tk_rqstp->rq_cred; 753 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
733 754
734 dprintk("RPC: %5u using %s cred %p to unwrap rpc data\n", 755 dprintk("RPC: %5u using %s cred %p to unwrap rpc data\n",
735 task->tk_pid, cred->cr_ops->cr_name, cred); 756 task->tk_pid, cred->cr_ops->cr_name, cred);
736 if (cred->cr_ops->crunwrap_resp) 757 if (cred->cr_ops->crunwrap_resp)
737 return cred->cr_ops->crunwrap_resp(task, decode, rqstp, 758 return cred->cr_ops->crunwrap_resp(task, decode, rqstp,
738 data, obj); 759 data, obj);
739 /* By default, we decode the arguments normally. */ 760 /* By default, we decode the arguments normally. */
740 return rpcauth_unwrap_req_decode(decode, rqstp, data, obj); 761 return rpcauth_unwrap_req_decode(decode, rqstp, data, obj);
741 } 762 }
742 763
743 int 764 int
744 rpcauth_refreshcred(struct rpc_task *task) 765 rpcauth_refreshcred(struct rpc_task *task)
745 { 766 {
746 struct rpc_cred *cred; 767 struct rpc_cred *cred;
747 int err; 768 int err;
748 769
749 cred = task->tk_rqstp->rq_cred; 770 cred = task->tk_rqstp->rq_cred;
750 if (cred == NULL) { 771 if (cred == NULL) {
751 err = rpcauth_bindcred(task, task->tk_msg.rpc_cred, task->tk_flags); 772 err = rpcauth_bindcred(task, task->tk_msg.rpc_cred, task->tk_flags);
752 if (err < 0) 773 if (err < 0)
753 goto out; 774 goto out;
754 cred = task->tk_rqstp->rq_cred; 775 cred = task->tk_rqstp->rq_cred;
755 } 776 }
756 dprintk("RPC: %5u refreshing %s cred %p\n", 777 dprintk("RPC: %5u refreshing %s cred %p\n",
757 task->tk_pid, cred->cr_auth->au_ops->au_name, cred); 778 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
758 779
759 err = cred->cr_ops->crrefresh(task); 780 err = cred->cr_ops->crrefresh(task);
760 out: 781 out:
761 if (err < 0) 782 if (err < 0)
762 task->tk_status = err; 783 task->tk_status = err;
763 return err; 784 return err;
764 } 785 }
765 786
766 void 787 void
767 rpcauth_invalcred(struct rpc_task *task) 788 rpcauth_invalcred(struct rpc_task *task)
768 { 789 {
769 struct rpc_cred *cred = task->tk_rqstp->rq_cred; 790 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
770 791
771 dprintk("RPC: %5u invalidating %s cred %p\n", 792 dprintk("RPC: %5u invalidating %s cred %p\n",
772 task->tk_pid, cred->cr_auth->au_ops->au_name, cred); 793 task->tk_pid, cred->cr_auth->au_ops->au_name, cred);
773 if (cred) 794 if (cred)
774 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); 795 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
775 } 796 }
776 797
777 int 798 int
778 rpcauth_uptodatecred(struct rpc_task *task) 799 rpcauth_uptodatecred(struct rpc_task *task)
779 { 800 {
780 struct rpc_cred *cred = task->tk_rqstp->rq_cred; 801 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
781 802
782 return cred == NULL || 803 return cred == NULL ||
783 test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0; 804 test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) != 0;
784 } 805 }
785 806
786 static struct shrinker rpc_cred_shrinker = { 807 static struct shrinker rpc_cred_shrinker = {
787 .shrink = rpcauth_cache_shrinker, 808 .shrink = rpcauth_cache_shrinker,
788 .seeks = DEFAULT_SEEKS, 809 .seeks = DEFAULT_SEEKS,
789 }; 810 };
790 811
791 int __init rpcauth_init_module(void) 812 int __init rpcauth_init_module(void)
792 { 813 {
793 int err; 814 int err;
794 815
795 err = rpc_init_authunix(); 816 err = rpc_init_authunix();
796 if (err < 0) 817 if (err < 0)
797 goto out1; 818 goto out1;
798 err = rpc_init_generic_auth(); 819 err = rpc_init_generic_auth();
799 if (err < 0) 820 if (err < 0)
800 goto out2; 821 goto out2;
801 register_shrinker(&rpc_cred_shrinker); 822 register_shrinker(&rpc_cred_shrinker);
802 return 0; 823 return 0;
803 out2: 824 out2:
804 rpc_destroy_authunix(); 825 rpc_destroy_authunix();
805 out1: 826 out1:
806 return err; 827 return err;
807 } 828 }
808 829
809 void rpcauth_remove_module(void) 830 void rpcauth_remove_module(void)
810 { 831 {
811 rpc_destroy_authunix(); 832 rpc_destroy_authunix();
812 rpc_destroy_generic_auth(); 833 rpc_destroy_generic_auth();
813 unregister_shrinker(&rpc_cred_shrinker); 834 unregister_shrinker(&rpc_cred_shrinker);
814 } 835 }
815 836
net/sunrpc/auth_generic.c
1 /* 1 /*
2 * Generic RPC credential 2 * Generic RPC credential
3 * 3 *
4 * Copyright (C) 2008, Trond Myklebust <Trond.Myklebust@netapp.com> 4 * Copyright (C) 2008, Trond Myklebust <Trond.Myklebust@netapp.com>
5 */ 5 */
6 6
7 #include <linux/err.h> 7 #include <linux/err.h>
8 #include <linux/slab.h> 8 #include <linux/slab.h>
9 #include <linux/types.h> 9 #include <linux/types.h>
10 #include <linux/module.h> 10 #include <linux/module.h>
11 #include <linux/sched.h> 11 #include <linux/sched.h>
12 #include <linux/sunrpc/auth.h> 12 #include <linux/sunrpc/auth.h>
13 #include <linux/sunrpc/clnt.h> 13 #include <linux/sunrpc/clnt.h>
14 #include <linux/sunrpc/debug.h> 14 #include <linux/sunrpc/debug.h>
15 #include <linux/sunrpc/sched.h> 15 #include <linux/sunrpc/sched.h>
16 16
17 #ifdef RPC_DEBUG 17 #ifdef RPC_DEBUG
18 # define RPCDBG_FACILITY RPCDBG_AUTH 18 # define RPCDBG_FACILITY RPCDBG_AUTH
19 #endif 19 #endif
20 20
21 #define RPC_MACHINE_CRED_USERID GLOBAL_ROOT_UID 21 #define RPC_MACHINE_CRED_USERID GLOBAL_ROOT_UID
22 #define RPC_MACHINE_CRED_GROUPID GLOBAL_ROOT_GID 22 #define RPC_MACHINE_CRED_GROUPID GLOBAL_ROOT_GID
23 23
24 struct generic_cred { 24 struct generic_cred {
25 struct rpc_cred gc_base; 25 struct rpc_cred gc_base;
26 struct auth_cred acred; 26 struct auth_cred acred;
27 }; 27 };
28 28
29 static struct rpc_auth generic_auth; 29 static struct rpc_auth generic_auth;
30 static const struct rpc_credops generic_credops; 30 static const struct rpc_credops generic_credops;
31 31
32 /* 32 /*
33 * Public call interface 33 * Public call interface
34 */ 34 */
35 struct rpc_cred *rpc_lookup_cred(void) 35 struct rpc_cred *rpc_lookup_cred(void)
36 { 36 {
37 return rpcauth_lookupcred(&generic_auth, 0); 37 return rpcauth_lookupcred(&generic_auth, 0);
38 } 38 }
39 EXPORT_SYMBOL_GPL(rpc_lookup_cred); 39 EXPORT_SYMBOL_GPL(rpc_lookup_cred);
40 40
41 /* 41 /*
42 * Public call interface for looking up machine creds. 42 * Public call interface for looking up machine creds.
43 */ 43 */
44 struct rpc_cred *rpc_lookup_machine_cred(const char *service_name) 44 struct rpc_cred *rpc_lookup_machine_cred(const char *service_name)
45 { 45 {
46 struct auth_cred acred = { 46 struct auth_cred acred = {
47 .uid = RPC_MACHINE_CRED_USERID, 47 .uid = RPC_MACHINE_CRED_USERID,
48 .gid = RPC_MACHINE_CRED_GROUPID, 48 .gid = RPC_MACHINE_CRED_GROUPID,
49 .principal = service_name, 49 .principal = service_name,
50 .machine_cred = 1, 50 .machine_cred = 1,
51 }; 51 };
52 52
53 dprintk("RPC: looking up machine cred for service %s\n", 53 dprintk("RPC: looking up machine cred for service %s\n",
54 service_name); 54 service_name);
55 return generic_auth.au_ops->lookup_cred(&generic_auth, &acred, 0); 55 return generic_auth.au_ops->lookup_cred(&generic_auth, &acred, 0);
56 } 56 }
57 EXPORT_SYMBOL_GPL(rpc_lookup_machine_cred); 57 EXPORT_SYMBOL_GPL(rpc_lookup_machine_cred);
58 58
59 static struct rpc_cred *generic_bind_cred(struct rpc_task *task, 59 static struct rpc_cred *generic_bind_cred(struct rpc_task *task,
60 struct rpc_cred *cred, int lookupflags) 60 struct rpc_cred *cred, int lookupflags)
61 { 61 {
62 struct rpc_auth *auth = task->tk_client->cl_auth; 62 struct rpc_auth *auth = task->tk_client->cl_auth;
63 struct auth_cred *acred = &container_of(cred, struct generic_cred, gc_base)->acred; 63 struct auth_cred *acred = &container_of(cred, struct generic_cred, gc_base)->acred;
64 64
65 return auth->au_ops->lookup_cred(auth, acred, lookupflags); 65 return auth->au_ops->lookup_cred(auth, acred, lookupflags);
66 } 66 }
67 67
68 /* 68 /*
69 * Lookup generic creds for current process 69 * Lookup generic creds for current process
70 */ 70 */
71 static struct rpc_cred * 71 static struct rpc_cred *
72 generic_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) 72 generic_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
73 { 73 {
74 return rpcauth_lookup_credcache(&generic_auth, acred, flags); 74 return rpcauth_lookup_credcache(&generic_auth, acred, flags);
75 } 75 }
76 76
77 static struct rpc_cred * 77 static struct rpc_cred *
78 generic_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) 78 generic_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
79 { 79 {
80 struct generic_cred *gcred; 80 struct generic_cred *gcred;
81 81
82 gcred = kmalloc(sizeof(*gcred), GFP_KERNEL); 82 gcred = kmalloc(sizeof(*gcred), GFP_KERNEL);
83 if (gcred == NULL) 83 if (gcred == NULL)
84 return ERR_PTR(-ENOMEM); 84 return ERR_PTR(-ENOMEM);
85 85
86 rpcauth_init_cred(&gcred->gc_base, acred, &generic_auth, &generic_credops); 86 rpcauth_init_cred(&gcred->gc_base, acred, &generic_auth, &generic_credops);
87 gcred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE; 87 gcred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_UPTODATE;
88 88
89 gcred->acred.uid = acred->uid; 89 gcred->acred.uid = acred->uid;
90 gcred->acred.gid = acred->gid; 90 gcred->acred.gid = acred->gid;
91 gcred->acred.group_info = acred->group_info; 91 gcred->acred.group_info = acred->group_info;
92 gcred->acred.ac_flags = 0;
92 if (gcred->acred.group_info != NULL) 93 if (gcred->acred.group_info != NULL)
93 get_group_info(gcred->acred.group_info); 94 get_group_info(gcred->acred.group_info);
94 gcred->acred.machine_cred = acred->machine_cred; 95 gcred->acred.machine_cred = acred->machine_cred;
95 gcred->acred.principal = acred->principal; 96 gcred->acred.principal = acred->principal;
96 97
97 dprintk("RPC: allocated %s cred %p for uid %d gid %d\n", 98 dprintk("RPC: allocated %s cred %p for uid %d gid %d\n",
98 gcred->acred.machine_cred ? "machine" : "generic", 99 gcred->acred.machine_cred ? "machine" : "generic",
99 gcred, 100 gcred,
100 from_kuid(&init_user_ns, acred->uid), 101 from_kuid(&init_user_ns, acred->uid),
101 from_kgid(&init_user_ns, acred->gid)); 102 from_kgid(&init_user_ns, acred->gid));
102 return &gcred->gc_base; 103 return &gcred->gc_base;
103 } 104 }
104 105
105 static void 106 static void
106 generic_free_cred(struct rpc_cred *cred) 107 generic_free_cred(struct rpc_cred *cred)
107 { 108 {
108 struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base); 109 struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base);
109 110
110 dprintk("RPC: generic_free_cred %p\n", gcred); 111 dprintk("RPC: generic_free_cred %p\n", gcred);
111 if (gcred->acred.group_info != NULL) 112 if (gcred->acred.group_info != NULL)
112 put_group_info(gcred->acred.group_info); 113 put_group_info(gcred->acred.group_info);
113 kfree(gcred); 114 kfree(gcred);
114 } 115 }
115 116
116 static void 117 static void
117 generic_free_cred_callback(struct rcu_head *head) 118 generic_free_cred_callback(struct rcu_head *head)
118 { 119 {
119 struct rpc_cred *cred = container_of(head, struct rpc_cred, cr_rcu); 120 struct rpc_cred *cred = container_of(head, struct rpc_cred, cr_rcu);
120 generic_free_cred(cred); 121 generic_free_cred(cred);
121 } 122 }
122 123
123 static void 124 static void
124 generic_destroy_cred(struct rpc_cred *cred) 125 generic_destroy_cred(struct rpc_cred *cred)
125 { 126 {
126 call_rcu(&cred->cr_rcu, generic_free_cred_callback); 127 call_rcu(&cred->cr_rcu, generic_free_cred_callback);
127 } 128 }
128 129
129 static int 130 static int
130 machine_cred_match(struct auth_cred *acred, struct generic_cred *gcred, int flags) 131 machine_cred_match(struct auth_cred *acred, struct generic_cred *gcred, int flags)
131 { 132 {
132 if (!gcred->acred.machine_cred || 133 if (!gcred->acred.machine_cred ||
133 gcred->acred.principal != acred->principal || 134 gcred->acred.principal != acred->principal ||
134 !uid_eq(gcred->acred.uid, acred->uid) || 135 !uid_eq(gcred->acred.uid, acred->uid) ||
135 !gid_eq(gcred->acred.gid, acred->gid)) 136 !gid_eq(gcred->acred.gid, acred->gid))
136 return 0; 137 return 0;
137 return 1; 138 return 1;
138 } 139 }
139 140
140 /* 141 /*
141 * Match credentials against current process creds. 142 * Match credentials against current process creds.
142 */ 143 */
143 static int 144 static int
144 generic_match(struct auth_cred *acred, struct rpc_cred *cred, int flags) 145 generic_match(struct auth_cred *acred, struct rpc_cred *cred, int flags)
145 { 146 {
146 struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base); 147 struct generic_cred *gcred = container_of(cred, struct generic_cred, gc_base);
147 int i; 148 int i;
148 149
149 if (acred->machine_cred) 150 if (acred->machine_cred)
150 return machine_cred_match(acred, gcred, flags); 151 return machine_cred_match(acred, gcred, flags);
151 152
152 if (!uid_eq(gcred->acred.uid, acred->uid) || 153 if (!uid_eq(gcred->acred.uid, acred->uid) ||
153 !gid_eq(gcred->acred.gid, acred->gid) || 154 !gid_eq(gcred->acred.gid, acred->gid) ||
154 gcred->acred.machine_cred != 0) 155 gcred->acred.machine_cred != 0)
155 goto out_nomatch; 156 goto out_nomatch;
156 157
157 /* Optimisation in the case where pointers are identical... */ 158 /* Optimisation in the case where pointers are identical... */
158 if (gcred->acred.group_info == acred->group_info) 159 if (gcred->acred.group_info == acred->group_info)
159 goto out_match; 160 goto out_match;
160 161
161 /* Slow path... */ 162 /* Slow path... */
162 if (gcred->acred.group_info->ngroups != acred->group_info->ngroups) 163 if (gcred->acred.group_info->ngroups != acred->group_info->ngroups)
163 goto out_nomatch; 164 goto out_nomatch;
164 for (i = 0; i < gcred->acred.group_info->ngroups; i++) { 165 for (i = 0; i < gcred->acred.group_info->ngroups; i++) {
165 if (!gid_eq(GROUP_AT(gcred->acred.group_info, i), 166 if (!gid_eq(GROUP_AT(gcred->acred.group_info, i),
166 GROUP_AT(acred->group_info, i))) 167 GROUP_AT(acred->group_info, i)))
167 goto out_nomatch; 168 goto out_nomatch;
168 } 169 }
169 out_match: 170 out_match:
170 return 1; 171 return 1;
171 out_nomatch: 172 out_nomatch:
172 return 0; 173 return 0;
173 } 174 }
174 175
175 int __init rpc_init_generic_auth(void) 176 int __init rpc_init_generic_auth(void)
176 { 177 {
177 return rpcauth_init_credcache(&generic_auth); 178 return rpcauth_init_credcache(&generic_auth);
178 } 179 }
179 180
180 void rpc_destroy_generic_auth(void) 181 void rpc_destroy_generic_auth(void)
181 { 182 {
182 rpcauth_destroy_credcache(&generic_auth); 183 rpcauth_destroy_credcache(&generic_auth);
183 } 184 }
184 185
186 /*
187 * Test the the current time (now) against the underlying credential key expiry
188 * minus a timeout and setup notification.
189 *
190 * The normal case:
191 * If 'now' is before the key expiry minus RPC_KEY_EXPIRE_TIMEO, set
192 * the RPC_CRED_NOTIFY_TIMEOUT flag to setup the underlying credential
193 * rpc_credops crmatch routine to notify this generic cred when it's key
194 * expiration is within RPC_KEY_EXPIRE_TIMEO, and return 0.
195 *
196 * The error case:
197 * If the underlying cred lookup fails, return -EACCES.
198 *
199 * The 'almost' error case:
200 * If 'now' is within key expiry minus RPC_KEY_EXPIRE_TIMEO, but not within
201 * key expiry minus RPC_KEY_EXPIRE_FAIL, set the RPC_CRED_EXPIRE_SOON bit
202 * on the acred ac_flags and return 0.
203 */
204 static int
205 generic_key_timeout(struct rpc_auth *auth, struct rpc_cred *cred)
206 {
207 struct auth_cred *acred = &container_of(cred, struct generic_cred,
208 gc_base)->acred;
209 struct rpc_cred *tcred;
210 int ret = 0;
211
212
213 /* Fast track for non crkey_timeout (no key) underlying credentials */
214 if (test_bit(RPC_CRED_NO_CRKEY_TIMEOUT, &acred->ac_flags))
215 return 0;
216
217 /* Fast track for the normal case */
218 if (test_bit(RPC_CRED_NOTIFY_TIMEOUT, &acred->ac_flags))
219 return 0;
220
221 /* lookup_cred either returns a valid referenced rpc_cred, or PTR_ERR */
222 tcred = auth->au_ops->lookup_cred(auth, acred, 0);
223 if (IS_ERR(tcred))
224 return -EACCES;
225
226 if (!tcred->cr_ops->crkey_timeout) {
227 set_bit(RPC_CRED_NO_CRKEY_TIMEOUT, &acred->ac_flags);
228 ret = 0;
229 goto out_put;
230 }
231
232 /* Test for the almost error case */
233 ret = tcred->cr_ops->crkey_timeout(tcred);
234 if (ret != 0) {
235 set_bit(RPC_CRED_KEY_EXPIRE_SOON, &acred->ac_flags);
236 ret = 0;
237 } else {
238 /* In case underlying cred key has been reset */
239 if (test_and_clear_bit(RPC_CRED_KEY_EXPIRE_SOON,
240 &acred->ac_flags))
241 dprintk("RPC: UID %d Credential key reset\n",
242 tcred->cr_uid);
243 /* set up fasttrack for the normal case */
244 set_bit(RPC_CRED_NOTIFY_TIMEOUT, &acred->ac_flags);
245 }
246
247 out_put:
248 put_rpccred(tcred);
249 return ret;
250 }
251
185 static const struct rpc_authops generic_auth_ops = { 252 static const struct rpc_authops generic_auth_ops = {
186 .owner = THIS_MODULE, 253 .owner = THIS_MODULE,
187 .au_name = "Generic", 254 .au_name = "Generic",
188 .lookup_cred = generic_lookup_cred, 255 .lookup_cred = generic_lookup_cred,
189 .crcreate = generic_create_cred, 256 .crcreate = generic_create_cred,
257 .key_timeout = generic_key_timeout,
190 }; 258 };
191 259
192 static struct rpc_auth generic_auth = { 260 static struct rpc_auth generic_auth = {
193 .au_ops = &generic_auth_ops, 261 .au_ops = &generic_auth_ops,
194 .au_count = ATOMIC_INIT(0), 262 .au_count = ATOMIC_INIT(0),
195 }; 263 };
196 264
265 static bool generic_key_to_expire(struct rpc_cred *cred)
266 {
267 struct auth_cred *acred = &container_of(cred, struct generic_cred,
268 gc_base)->acred;
269 bool ret;
270
271 get_rpccred(cred);
272 ret = test_bit(RPC_CRED_KEY_EXPIRE_SOON, &acred->ac_flags);
273 put_rpccred(cred);
274
275 return ret;
276 }
277
197 static const struct rpc_credops generic_credops = { 278 static const struct rpc_credops generic_credops = {
198 .cr_name = "Generic cred", 279 .cr_name = "Generic cred",
199 .crdestroy = generic_destroy_cred, 280 .crdestroy = generic_destroy_cred,
200 .crbind = generic_bind_cred, 281 .crbind = generic_bind_cred,
201 .crmatch = generic_match, 282 .crmatch = generic_match,
283 .crkey_to_expire = generic_key_to_expire,
202 }; 284 };
203 285
net/sunrpc/auth_gss/auth_gss.c
1 /* 1 /*
2 * linux/net/sunrpc/auth_gss/auth_gss.c 2 * linux/net/sunrpc/auth_gss/auth_gss.c
3 * 3 *
4 * RPCSEC_GSS client authentication. 4 * RPCSEC_GSS client authentication.
5 * 5 *
6 * Copyright (c) 2000 The Regents of the University of Michigan. 6 * Copyright (c) 2000 The Regents of the University of Michigan.
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Dug Song <dugsong@monkey.org> 9 * Dug Song <dugsong@monkey.org>
10 * Andy Adamson <andros@umich.edu> 10 * Andy Adamson <andros@umich.edu>
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
15 * 15 *
16 * 1. Redistributions of source code must retain the above copyright 16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer. 17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright 18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the 19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution. 20 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the University nor the names of its 21 * 3. Neither the name of the University nor the names of its
22 * contributors may be used to endorse or promote products derived 22 * contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission. 23 * from this software without specific prior written permission.
24 * 24 *
25 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 25 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
26 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 26 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
27 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 27 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
32 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 32 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 34 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */ 36 */
37 37
38 38
39 #include <linux/module.h> 39 #include <linux/module.h>
40 #include <linux/init.h> 40 #include <linux/init.h>
41 #include <linux/types.h> 41 #include <linux/types.h>
42 #include <linux/slab.h> 42 #include <linux/slab.h>
43 #include <linux/sched.h> 43 #include <linux/sched.h>
44 #include <linux/pagemap.h> 44 #include <linux/pagemap.h>
45 #include <linux/sunrpc/clnt.h> 45 #include <linux/sunrpc/clnt.h>
46 #include <linux/sunrpc/auth.h> 46 #include <linux/sunrpc/auth.h>
47 #include <linux/sunrpc/auth_gss.h> 47 #include <linux/sunrpc/auth_gss.h>
48 #include <linux/sunrpc/svcauth_gss.h> 48 #include <linux/sunrpc/svcauth_gss.h>
49 #include <linux/sunrpc/gss_err.h> 49 #include <linux/sunrpc/gss_err.h>
50 #include <linux/workqueue.h> 50 #include <linux/workqueue.h>
51 #include <linux/sunrpc/rpc_pipe_fs.h> 51 #include <linux/sunrpc/rpc_pipe_fs.h>
52 #include <linux/sunrpc/gss_api.h> 52 #include <linux/sunrpc/gss_api.h>
53 #include <asm/uaccess.h> 53 #include <asm/uaccess.h>
54 #include <linux/hashtable.h> 54 #include <linux/hashtable.h>
55 55
56 #include "../netns.h" 56 #include "../netns.h"
57 57
58 static const struct rpc_authops authgss_ops; 58 static const struct rpc_authops authgss_ops;
59 59
60 static const struct rpc_credops gss_credops; 60 static const struct rpc_credops gss_credops;
61 static const struct rpc_credops gss_nullops; 61 static const struct rpc_credops gss_nullops;
62 62
63 #define GSS_RETRY_EXPIRED 5 63 #define GSS_RETRY_EXPIRED 5
64 static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED; 64 static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED;
65 65
66 #define GSS_KEY_EXPIRE_TIMEO 240
67 static unsigned int gss_key_expire_timeo = GSS_KEY_EXPIRE_TIMEO;
68
66 #ifdef RPC_DEBUG 69 #ifdef RPC_DEBUG
67 # define RPCDBG_FACILITY RPCDBG_AUTH 70 # define RPCDBG_FACILITY RPCDBG_AUTH
68 #endif 71 #endif
69 72
70 #define GSS_CRED_SLACK (RPC_MAX_AUTH_SIZE * 2) 73 #define GSS_CRED_SLACK (RPC_MAX_AUTH_SIZE * 2)
71 /* length of a krb5 verifier (48), plus data added before arguments when 74 /* length of a krb5 verifier (48), plus data added before arguments when
72 * using integrity (two 4-byte integers): */ 75 * using integrity (two 4-byte integers): */
73 #define GSS_VERF_SLACK 100 76 #define GSS_VERF_SLACK 100
74 77
75 static DEFINE_HASHTABLE(gss_auth_hash_table, 16); 78 static DEFINE_HASHTABLE(gss_auth_hash_table, 16);
76 static DEFINE_SPINLOCK(gss_auth_hash_lock); 79 static DEFINE_SPINLOCK(gss_auth_hash_lock);
77 80
78 struct gss_pipe { 81 struct gss_pipe {
79 struct rpc_pipe_dir_object pdo; 82 struct rpc_pipe_dir_object pdo;
80 struct rpc_pipe *pipe; 83 struct rpc_pipe *pipe;
81 struct rpc_clnt *clnt; 84 struct rpc_clnt *clnt;
82 const char *name; 85 const char *name;
83 struct kref kref; 86 struct kref kref;
84 }; 87 };
85 88
86 struct gss_auth { 89 struct gss_auth {
87 struct kref kref; 90 struct kref kref;
88 struct hlist_node hash; 91 struct hlist_node hash;
89 struct rpc_auth rpc_auth; 92 struct rpc_auth rpc_auth;
90 struct gss_api_mech *mech; 93 struct gss_api_mech *mech;
91 enum rpc_gss_svc service; 94 enum rpc_gss_svc service;
92 struct rpc_clnt *client; 95 struct rpc_clnt *client;
93 struct net *net; 96 struct net *net;
94 /* 97 /*
95 * There are two upcall pipes; dentry[1], named "gssd", is used 98 * There are two upcall pipes; dentry[1], named "gssd", is used
96 * for the new text-based upcall; dentry[0] is named after the 99 * for the new text-based upcall; dentry[0] is named after the
97 * mechanism (for example, "krb5") and exists for 100 * mechanism (for example, "krb5") and exists for
98 * backwards-compatibility with older gssd's. 101 * backwards-compatibility with older gssd's.
99 */ 102 */
100 struct gss_pipe *gss_pipe[2]; 103 struct gss_pipe *gss_pipe[2];
101 const char *target_name; 104 const char *target_name;
102 }; 105 };
103 106
104 /* pipe_version >= 0 if and only if someone has a pipe open. */ 107 /* pipe_version >= 0 if and only if someone has a pipe open. */
105 static DEFINE_SPINLOCK(pipe_version_lock); 108 static DEFINE_SPINLOCK(pipe_version_lock);
106 static struct rpc_wait_queue pipe_version_rpc_waitqueue; 109 static struct rpc_wait_queue pipe_version_rpc_waitqueue;
107 static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue); 110 static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue);
108 111
109 static void gss_free_ctx(struct gss_cl_ctx *); 112 static void gss_free_ctx(struct gss_cl_ctx *);
110 static const struct rpc_pipe_ops gss_upcall_ops_v0; 113 static const struct rpc_pipe_ops gss_upcall_ops_v0;
111 static const struct rpc_pipe_ops gss_upcall_ops_v1; 114 static const struct rpc_pipe_ops gss_upcall_ops_v1;
112 115
113 static inline struct gss_cl_ctx * 116 static inline struct gss_cl_ctx *
114 gss_get_ctx(struct gss_cl_ctx *ctx) 117 gss_get_ctx(struct gss_cl_ctx *ctx)
115 { 118 {
116 atomic_inc(&ctx->count); 119 atomic_inc(&ctx->count);
117 return ctx; 120 return ctx;
118 } 121 }
119 122
120 static inline void 123 static inline void
121 gss_put_ctx(struct gss_cl_ctx *ctx) 124 gss_put_ctx(struct gss_cl_ctx *ctx)
122 { 125 {
123 if (atomic_dec_and_test(&ctx->count)) 126 if (atomic_dec_and_test(&ctx->count))
124 gss_free_ctx(ctx); 127 gss_free_ctx(ctx);
125 } 128 }
126 129
127 /* gss_cred_set_ctx: 130 /* gss_cred_set_ctx:
128 * called by gss_upcall_callback and gss_create_upcall in order 131 * called by gss_upcall_callback and gss_create_upcall in order
129 * to set the gss context. The actual exchange of an old context 132 * to set the gss context. The actual exchange of an old context
130 * and a new one is protected by the pipe->lock. 133 * and a new one is protected by the pipe->lock.
131 */ 134 */
132 static void 135 static void
133 gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx) 136 gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx)
134 { 137 {
135 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base); 138 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
136 139
137 if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags)) 140 if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags))
138 return; 141 return;
139 gss_get_ctx(ctx); 142 gss_get_ctx(ctx);
140 rcu_assign_pointer(gss_cred->gc_ctx, ctx); 143 rcu_assign_pointer(gss_cred->gc_ctx, ctx);
141 set_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); 144 set_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
142 smp_mb__before_clear_bit(); 145 smp_mb__before_clear_bit();
143 clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags); 146 clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags);
144 } 147 }
145 148
146 static const void * 149 static const void *
147 simple_get_bytes(const void *p, const void *end, void *res, size_t len) 150 simple_get_bytes(const void *p, const void *end, void *res, size_t len)
148 { 151 {
149 const void *q = (const void *)((const char *)p + len); 152 const void *q = (const void *)((const char *)p + len);
150 if (unlikely(q > end || q < p)) 153 if (unlikely(q > end || q < p))
151 return ERR_PTR(-EFAULT); 154 return ERR_PTR(-EFAULT);
152 memcpy(res, p, len); 155 memcpy(res, p, len);
153 return q; 156 return q;
154 } 157 }
155 158
156 static inline const void * 159 static inline const void *
157 simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest) 160 simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest)
158 { 161 {
159 const void *q; 162 const void *q;
160 unsigned int len; 163 unsigned int len;
161 164
162 p = simple_get_bytes(p, end, &len, sizeof(len)); 165 p = simple_get_bytes(p, end, &len, sizeof(len));
163 if (IS_ERR(p)) 166 if (IS_ERR(p))
164 return p; 167 return p;
165 q = (const void *)((const char *)p + len); 168 q = (const void *)((const char *)p + len);
166 if (unlikely(q > end || q < p)) 169 if (unlikely(q > end || q < p))
167 return ERR_PTR(-EFAULT); 170 return ERR_PTR(-EFAULT);
168 dest->data = kmemdup(p, len, GFP_NOFS); 171 dest->data = kmemdup(p, len, GFP_NOFS);
169 if (unlikely(dest->data == NULL)) 172 if (unlikely(dest->data == NULL))
170 return ERR_PTR(-ENOMEM); 173 return ERR_PTR(-ENOMEM);
171 dest->len = len; 174 dest->len = len;
172 return q; 175 return q;
173 } 176 }
174 177
175 static struct gss_cl_ctx * 178 static struct gss_cl_ctx *
176 gss_cred_get_ctx(struct rpc_cred *cred) 179 gss_cred_get_ctx(struct rpc_cred *cred)
177 { 180 {
178 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base); 181 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
179 struct gss_cl_ctx *ctx = NULL; 182 struct gss_cl_ctx *ctx = NULL;
180 183
181 rcu_read_lock(); 184 rcu_read_lock();
182 if (gss_cred->gc_ctx) 185 if (gss_cred->gc_ctx)
183 ctx = gss_get_ctx(gss_cred->gc_ctx); 186 ctx = gss_get_ctx(gss_cred->gc_ctx);
184 rcu_read_unlock(); 187 rcu_read_unlock();
185 return ctx; 188 return ctx;
186 } 189 }
187 190
188 static struct gss_cl_ctx * 191 static struct gss_cl_ctx *
189 gss_alloc_context(void) 192 gss_alloc_context(void)
190 { 193 {
191 struct gss_cl_ctx *ctx; 194 struct gss_cl_ctx *ctx;
192 195
193 ctx = kzalloc(sizeof(*ctx), GFP_NOFS); 196 ctx = kzalloc(sizeof(*ctx), GFP_NOFS);
194 if (ctx != NULL) { 197 if (ctx != NULL) {
195 ctx->gc_proc = RPC_GSS_PROC_DATA; 198 ctx->gc_proc = RPC_GSS_PROC_DATA;
196 ctx->gc_seq = 1; /* NetApp 6.4R1 doesn't accept seq. no. 0 */ 199 ctx->gc_seq = 1; /* NetApp 6.4R1 doesn't accept seq. no. 0 */
197 spin_lock_init(&ctx->gc_seq_lock); 200 spin_lock_init(&ctx->gc_seq_lock);
198 atomic_set(&ctx->count,1); 201 atomic_set(&ctx->count,1);
199 } 202 }
200 return ctx; 203 return ctx;
201 } 204 }
202 205
203 #define GSSD_MIN_TIMEOUT (60 * 60) 206 #define GSSD_MIN_TIMEOUT (60 * 60)
204 static const void * 207 static const void *
205 gss_fill_context(const void *p, const void *end, struct gss_cl_ctx *ctx, struct gss_api_mech *gm) 208 gss_fill_context(const void *p, const void *end, struct gss_cl_ctx *ctx, struct gss_api_mech *gm)
206 { 209 {
207 const void *q; 210 const void *q;
208 unsigned int seclen; 211 unsigned int seclen;
209 unsigned int timeout; 212 unsigned int timeout;
210 unsigned long now = jiffies; 213 unsigned long now = jiffies;
211 u32 window_size; 214 u32 window_size;
212 int ret; 215 int ret;
213 216
214 /* First unsigned int gives the remaining lifetime in seconds of the 217 /* First unsigned int gives the remaining lifetime in seconds of the
215 * credential - e.g. the remaining TGT lifetime for Kerberos or 218 * credential - e.g. the remaining TGT lifetime for Kerberos or
216 * the -t value passed to GSSD. 219 * the -t value passed to GSSD.
217 */ 220 */
218 p = simple_get_bytes(p, end, &timeout, sizeof(timeout)); 221 p = simple_get_bytes(p, end, &timeout, sizeof(timeout));
219 if (IS_ERR(p)) 222 if (IS_ERR(p))
220 goto err; 223 goto err;
221 if (timeout == 0) 224 if (timeout == 0)
222 timeout = GSSD_MIN_TIMEOUT; 225 timeout = GSSD_MIN_TIMEOUT;
223 ctx->gc_expiry = now + ((unsigned long)timeout * HZ); 226 ctx->gc_expiry = now + ((unsigned long)timeout * HZ);
224 /* Sequence number window. Determines the maximum number of 227 /* Sequence number window. Determines the maximum number of
225 * simultaneous requests 228 * simultaneous requests
226 */ 229 */
227 p = simple_get_bytes(p, end, &window_size, sizeof(window_size)); 230 p = simple_get_bytes(p, end, &window_size, sizeof(window_size));
228 if (IS_ERR(p)) 231 if (IS_ERR(p))
229 goto err; 232 goto err;
230 ctx->gc_win = window_size; 233 ctx->gc_win = window_size;
231 /* gssd signals an error by passing ctx->gc_win = 0: */ 234 /* gssd signals an error by passing ctx->gc_win = 0: */
232 if (ctx->gc_win == 0) { 235 if (ctx->gc_win == 0) {
233 /* 236 /*
234 * in which case, p points to an error code. Anything other 237 * in which case, p points to an error code. Anything other
235 * than -EKEYEXPIRED gets converted to -EACCES. 238 * than -EKEYEXPIRED gets converted to -EACCES.
236 */ 239 */
237 p = simple_get_bytes(p, end, &ret, sizeof(ret)); 240 p = simple_get_bytes(p, end, &ret, sizeof(ret));
238 if (!IS_ERR(p)) 241 if (!IS_ERR(p))
239 p = (ret == -EKEYEXPIRED) ? ERR_PTR(-EKEYEXPIRED) : 242 p = (ret == -EKEYEXPIRED) ? ERR_PTR(-EKEYEXPIRED) :
240 ERR_PTR(-EACCES); 243 ERR_PTR(-EACCES);
241 goto err; 244 goto err;
242 } 245 }
243 /* copy the opaque wire context */ 246 /* copy the opaque wire context */
244 p = simple_get_netobj(p, end, &ctx->gc_wire_ctx); 247 p = simple_get_netobj(p, end, &ctx->gc_wire_ctx);
245 if (IS_ERR(p)) 248 if (IS_ERR(p))
246 goto err; 249 goto err;
247 /* import the opaque security context */ 250 /* import the opaque security context */
248 p = simple_get_bytes(p, end, &seclen, sizeof(seclen)); 251 p = simple_get_bytes(p, end, &seclen, sizeof(seclen));
249 if (IS_ERR(p)) 252 if (IS_ERR(p))
250 goto err; 253 goto err;
251 q = (const void *)((const char *)p + seclen); 254 q = (const void *)((const char *)p + seclen);
252 if (unlikely(q > end || q < p)) { 255 if (unlikely(q > end || q < p)) {
253 p = ERR_PTR(-EFAULT); 256 p = ERR_PTR(-EFAULT);
254 goto err; 257 goto err;
255 } 258 }
256 ret = gss_import_sec_context(p, seclen, gm, &ctx->gc_gss_ctx, NULL, GFP_NOFS); 259 ret = gss_import_sec_context(p, seclen, gm, &ctx->gc_gss_ctx, NULL, GFP_NOFS);
257 if (ret < 0) { 260 if (ret < 0) {
258 p = ERR_PTR(ret); 261 p = ERR_PTR(ret);
259 goto err; 262 goto err;
260 } 263 }
261 dprintk("RPC: %s Success. gc_expiry %lu now %lu timeout %u\n", 264 dprintk("RPC: %s Success. gc_expiry %lu now %lu timeout %u\n",
262 __func__, ctx->gc_expiry, now, timeout); 265 __func__, ctx->gc_expiry, now, timeout);
263 return q; 266 return q;
264 err: 267 err:
265 dprintk("RPC: %s returns error %ld\n", __func__, -PTR_ERR(p)); 268 dprintk("RPC: %s returns error %ld\n", __func__, -PTR_ERR(p));
266 return p; 269 return p;
267 } 270 }
268 271
269 #define UPCALL_BUF_LEN 128 272 #define UPCALL_BUF_LEN 128
270 273
271 struct gss_upcall_msg { 274 struct gss_upcall_msg {
272 atomic_t count; 275 atomic_t count;
273 kuid_t uid; 276 kuid_t uid;
274 struct rpc_pipe_msg msg; 277 struct rpc_pipe_msg msg;
275 struct list_head list; 278 struct list_head list;
276 struct gss_auth *auth; 279 struct gss_auth *auth;
277 struct rpc_pipe *pipe; 280 struct rpc_pipe *pipe;
278 struct rpc_wait_queue rpc_waitqueue; 281 struct rpc_wait_queue rpc_waitqueue;
279 wait_queue_head_t waitqueue; 282 wait_queue_head_t waitqueue;
280 struct gss_cl_ctx *ctx; 283 struct gss_cl_ctx *ctx;
281 char databuf[UPCALL_BUF_LEN]; 284 char databuf[UPCALL_BUF_LEN];
282 }; 285 };
283 286
284 static int get_pipe_version(struct net *net) 287 static int get_pipe_version(struct net *net)
285 { 288 {
286 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 289 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
287 int ret; 290 int ret;
288 291
289 spin_lock(&pipe_version_lock); 292 spin_lock(&pipe_version_lock);
290 if (sn->pipe_version >= 0) { 293 if (sn->pipe_version >= 0) {
291 atomic_inc(&sn->pipe_users); 294 atomic_inc(&sn->pipe_users);
292 ret = sn->pipe_version; 295 ret = sn->pipe_version;
293 } else 296 } else
294 ret = -EAGAIN; 297 ret = -EAGAIN;
295 spin_unlock(&pipe_version_lock); 298 spin_unlock(&pipe_version_lock);
296 return ret; 299 return ret;
297 } 300 }
298 301
299 static void put_pipe_version(struct net *net) 302 static void put_pipe_version(struct net *net)
300 { 303 {
301 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 304 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
302 305
303 if (atomic_dec_and_lock(&sn->pipe_users, &pipe_version_lock)) { 306 if (atomic_dec_and_lock(&sn->pipe_users, &pipe_version_lock)) {
304 sn->pipe_version = -1; 307 sn->pipe_version = -1;
305 spin_unlock(&pipe_version_lock); 308 spin_unlock(&pipe_version_lock);
306 } 309 }
307 } 310 }
308 311
309 static void 312 static void
310 gss_release_msg(struct gss_upcall_msg *gss_msg) 313 gss_release_msg(struct gss_upcall_msg *gss_msg)
311 { 314 {
312 struct net *net = gss_msg->auth->net; 315 struct net *net = gss_msg->auth->net;
313 if (!atomic_dec_and_test(&gss_msg->count)) 316 if (!atomic_dec_and_test(&gss_msg->count))
314 return; 317 return;
315 put_pipe_version(net); 318 put_pipe_version(net);
316 BUG_ON(!list_empty(&gss_msg->list)); 319 BUG_ON(!list_empty(&gss_msg->list));
317 if (gss_msg->ctx != NULL) 320 if (gss_msg->ctx != NULL)
318 gss_put_ctx(gss_msg->ctx); 321 gss_put_ctx(gss_msg->ctx);
319 rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue); 322 rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue);
320 kfree(gss_msg); 323 kfree(gss_msg);
321 } 324 }
322 325
323 static struct gss_upcall_msg * 326 static struct gss_upcall_msg *
324 __gss_find_upcall(struct rpc_pipe *pipe, kuid_t uid) 327 __gss_find_upcall(struct rpc_pipe *pipe, kuid_t uid)
325 { 328 {
326 struct gss_upcall_msg *pos; 329 struct gss_upcall_msg *pos;
327 list_for_each_entry(pos, &pipe->in_downcall, list) { 330 list_for_each_entry(pos, &pipe->in_downcall, list) {
328 if (!uid_eq(pos->uid, uid)) 331 if (!uid_eq(pos->uid, uid))
329 continue; 332 continue;
330 atomic_inc(&pos->count); 333 atomic_inc(&pos->count);
331 dprintk("RPC: %s found msg %p\n", __func__, pos); 334 dprintk("RPC: %s found msg %p\n", __func__, pos);
332 return pos; 335 return pos;
333 } 336 }
334 dprintk("RPC: %s found nothing\n", __func__); 337 dprintk("RPC: %s found nothing\n", __func__);
335 return NULL; 338 return NULL;
336 } 339 }
337 340
338 /* Try to add an upcall to the pipefs queue. 341 /* Try to add an upcall to the pipefs queue.
339 * If an upcall owned by our uid already exists, then we return a reference 342 * If an upcall owned by our uid already exists, then we return a reference
340 * to that upcall instead of adding the new upcall. 343 * to that upcall instead of adding the new upcall.
341 */ 344 */
342 static inline struct gss_upcall_msg * 345 static inline struct gss_upcall_msg *
343 gss_add_msg(struct gss_upcall_msg *gss_msg) 346 gss_add_msg(struct gss_upcall_msg *gss_msg)
344 { 347 {
345 struct rpc_pipe *pipe = gss_msg->pipe; 348 struct rpc_pipe *pipe = gss_msg->pipe;
346 struct gss_upcall_msg *old; 349 struct gss_upcall_msg *old;
347 350
348 spin_lock(&pipe->lock); 351 spin_lock(&pipe->lock);
349 old = __gss_find_upcall(pipe, gss_msg->uid); 352 old = __gss_find_upcall(pipe, gss_msg->uid);
350 if (old == NULL) { 353 if (old == NULL) {
351 atomic_inc(&gss_msg->count); 354 atomic_inc(&gss_msg->count);
352 list_add(&gss_msg->list, &pipe->in_downcall); 355 list_add(&gss_msg->list, &pipe->in_downcall);
353 } else 356 } else
354 gss_msg = old; 357 gss_msg = old;
355 spin_unlock(&pipe->lock); 358 spin_unlock(&pipe->lock);
356 return gss_msg; 359 return gss_msg;
357 } 360 }
358 361
359 static void 362 static void
360 __gss_unhash_msg(struct gss_upcall_msg *gss_msg) 363 __gss_unhash_msg(struct gss_upcall_msg *gss_msg)
361 { 364 {
362 list_del_init(&gss_msg->list); 365 list_del_init(&gss_msg->list);
363 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno); 366 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno);
364 wake_up_all(&gss_msg->waitqueue); 367 wake_up_all(&gss_msg->waitqueue);
365 atomic_dec(&gss_msg->count); 368 atomic_dec(&gss_msg->count);
366 } 369 }
367 370
368 static void 371 static void
369 gss_unhash_msg(struct gss_upcall_msg *gss_msg) 372 gss_unhash_msg(struct gss_upcall_msg *gss_msg)
370 { 373 {
371 struct rpc_pipe *pipe = gss_msg->pipe; 374 struct rpc_pipe *pipe = gss_msg->pipe;
372 375
373 if (list_empty(&gss_msg->list)) 376 if (list_empty(&gss_msg->list))
374 return; 377 return;
375 spin_lock(&pipe->lock); 378 spin_lock(&pipe->lock);
376 if (!list_empty(&gss_msg->list)) 379 if (!list_empty(&gss_msg->list))
377 __gss_unhash_msg(gss_msg); 380 __gss_unhash_msg(gss_msg);
378 spin_unlock(&pipe->lock); 381 spin_unlock(&pipe->lock);
379 } 382 }
380 383
381 static void 384 static void
382 gss_handle_downcall_result(struct gss_cred *gss_cred, struct gss_upcall_msg *gss_msg) 385 gss_handle_downcall_result(struct gss_cred *gss_cred, struct gss_upcall_msg *gss_msg)
383 { 386 {
384 switch (gss_msg->msg.errno) { 387 switch (gss_msg->msg.errno) {
385 case 0: 388 case 0:
386 if (gss_msg->ctx == NULL) 389 if (gss_msg->ctx == NULL)
387 break; 390 break;
388 clear_bit(RPCAUTH_CRED_NEGATIVE, &gss_cred->gc_base.cr_flags); 391 clear_bit(RPCAUTH_CRED_NEGATIVE, &gss_cred->gc_base.cr_flags);
389 gss_cred_set_ctx(&gss_cred->gc_base, gss_msg->ctx); 392 gss_cred_set_ctx(&gss_cred->gc_base, gss_msg->ctx);
390 break; 393 break;
391 case -EKEYEXPIRED: 394 case -EKEYEXPIRED:
392 set_bit(RPCAUTH_CRED_NEGATIVE, &gss_cred->gc_base.cr_flags); 395 set_bit(RPCAUTH_CRED_NEGATIVE, &gss_cred->gc_base.cr_flags);
393 } 396 }
394 gss_cred->gc_upcall_timestamp = jiffies; 397 gss_cred->gc_upcall_timestamp = jiffies;
395 gss_cred->gc_upcall = NULL; 398 gss_cred->gc_upcall = NULL;
396 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno); 399 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno);
397 } 400 }
398 401
399 static void 402 static void
400 gss_upcall_callback(struct rpc_task *task) 403 gss_upcall_callback(struct rpc_task *task)
401 { 404 {
402 struct gss_cred *gss_cred = container_of(task->tk_rqstp->rq_cred, 405 struct gss_cred *gss_cred = container_of(task->tk_rqstp->rq_cred,
403 struct gss_cred, gc_base); 406 struct gss_cred, gc_base);
404 struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall; 407 struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall;
405 struct rpc_pipe *pipe = gss_msg->pipe; 408 struct rpc_pipe *pipe = gss_msg->pipe;
406 409
407 spin_lock(&pipe->lock); 410 spin_lock(&pipe->lock);
408 gss_handle_downcall_result(gss_cred, gss_msg); 411 gss_handle_downcall_result(gss_cred, gss_msg);
409 spin_unlock(&pipe->lock); 412 spin_unlock(&pipe->lock);
410 task->tk_status = gss_msg->msg.errno; 413 task->tk_status = gss_msg->msg.errno;
411 gss_release_msg(gss_msg); 414 gss_release_msg(gss_msg);
412 } 415 }
413 416
414 static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg) 417 static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg)
415 { 418 {
416 uid_t uid = from_kuid(&init_user_ns, gss_msg->uid); 419 uid_t uid = from_kuid(&init_user_ns, gss_msg->uid);
417 memcpy(gss_msg->databuf, &uid, sizeof(uid)); 420 memcpy(gss_msg->databuf, &uid, sizeof(uid));
418 gss_msg->msg.data = gss_msg->databuf; 421 gss_msg->msg.data = gss_msg->databuf;
419 gss_msg->msg.len = sizeof(uid); 422 gss_msg->msg.len = sizeof(uid);
420 BUG_ON(sizeof(uid) > UPCALL_BUF_LEN); 423 BUG_ON(sizeof(uid) > UPCALL_BUF_LEN);
421 } 424 }
422 425
423 static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg, 426 static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
424 const char *service_name, 427 const char *service_name,
425 const char *target_name) 428 const char *target_name)
426 { 429 {
427 struct gss_api_mech *mech = gss_msg->auth->mech; 430 struct gss_api_mech *mech = gss_msg->auth->mech;
428 char *p = gss_msg->databuf; 431 char *p = gss_msg->databuf;
429 int len = 0; 432 int len = 0;
430 433
431 gss_msg->msg.len = sprintf(gss_msg->databuf, "mech=%s uid=%d ", 434 gss_msg->msg.len = sprintf(gss_msg->databuf, "mech=%s uid=%d ",
432 mech->gm_name, 435 mech->gm_name,
433 from_kuid(&init_user_ns, gss_msg->uid)); 436 from_kuid(&init_user_ns, gss_msg->uid));
434 p += gss_msg->msg.len; 437 p += gss_msg->msg.len;
435 if (target_name) { 438 if (target_name) {
436 len = sprintf(p, "target=%s ", target_name); 439 len = sprintf(p, "target=%s ", target_name);
437 p += len; 440 p += len;
438 gss_msg->msg.len += len; 441 gss_msg->msg.len += len;
439 } 442 }
440 if (service_name != NULL) { 443 if (service_name != NULL) {
441 len = sprintf(p, "service=%s ", service_name); 444 len = sprintf(p, "service=%s ", service_name);
442 p += len; 445 p += len;
443 gss_msg->msg.len += len; 446 gss_msg->msg.len += len;
444 } 447 }
445 if (mech->gm_upcall_enctypes) { 448 if (mech->gm_upcall_enctypes) {
446 len = sprintf(p, "enctypes=%s ", mech->gm_upcall_enctypes); 449 len = sprintf(p, "enctypes=%s ", mech->gm_upcall_enctypes);
447 p += len; 450 p += len;
448 gss_msg->msg.len += len; 451 gss_msg->msg.len += len;
449 } 452 }
450 len = sprintf(p, "\n"); 453 len = sprintf(p, "\n");
451 gss_msg->msg.len += len; 454 gss_msg->msg.len += len;
452 455
453 gss_msg->msg.data = gss_msg->databuf; 456 gss_msg->msg.data = gss_msg->databuf;
454 BUG_ON(gss_msg->msg.len > UPCALL_BUF_LEN); 457 BUG_ON(gss_msg->msg.len > UPCALL_BUF_LEN);
455 } 458 }
456 459
457 static struct gss_upcall_msg * 460 static struct gss_upcall_msg *
458 gss_alloc_msg(struct gss_auth *gss_auth, 461 gss_alloc_msg(struct gss_auth *gss_auth,
459 kuid_t uid, const char *service_name) 462 kuid_t uid, const char *service_name)
460 { 463 {
461 struct gss_upcall_msg *gss_msg; 464 struct gss_upcall_msg *gss_msg;
462 int vers; 465 int vers;
463 466
464 gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS); 467 gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS);
465 if (gss_msg == NULL) 468 if (gss_msg == NULL)
466 return ERR_PTR(-ENOMEM); 469 return ERR_PTR(-ENOMEM);
467 vers = get_pipe_version(gss_auth->net); 470 vers = get_pipe_version(gss_auth->net);
468 if (vers < 0) { 471 if (vers < 0) {
469 kfree(gss_msg); 472 kfree(gss_msg);
470 return ERR_PTR(vers); 473 return ERR_PTR(vers);
471 } 474 }
472 gss_msg->pipe = gss_auth->gss_pipe[vers]->pipe; 475 gss_msg->pipe = gss_auth->gss_pipe[vers]->pipe;
473 INIT_LIST_HEAD(&gss_msg->list); 476 INIT_LIST_HEAD(&gss_msg->list);
474 rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq"); 477 rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq");
475 init_waitqueue_head(&gss_msg->waitqueue); 478 init_waitqueue_head(&gss_msg->waitqueue);
476 atomic_set(&gss_msg->count, 1); 479 atomic_set(&gss_msg->count, 1);
477 gss_msg->uid = uid; 480 gss_msg->uid = uid;
478 gss_msg->auth = gss_auth; 481 gss_msg->auth = gss_auth;
479 switch (vers) { 482 switch (vers) {
480 case 0: 483 case 0:
481 gss_encode_v0_msg(gss_msg); 484 gss_encode_v0_msg(gss_msg);
482 default: 485 default:
483 gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name); 486 gss_encode_v1_msg(gss_msg, service_name, gss_auth->target_name);
484 }; 487 };
485 return gss_msg; 488 return gss_msg;
486 } 489 }
487 490
488 static struct gss_upcall_msg * 491 static struct gss_upcall_msg *
489 gss_setup_upcall(struct gss_auth *gss_auth, struct rpc_cred *cred) 492 gss_setup_upcall(struct gss_auth *gss_auth, struct rpc_cred *cred)
490 { 493 {
491 struct gss_cred *gss_cred = container_of(cred, 494 struct gss_cred *gss_cred = container_of(cred,
492 struct gss_cred, gc_base); 495 struct gss_cred, gc_base);
493 struct gss_upcall_msg *gss_new, *gss_msg; 496 struct gss_upcall_msg *gss_new, *gss_msg;
494 kuid_t uid = cred->cr_uid; 497 kuid_t uid = cred->cr_uid;
495 498
496 gss_new = gss_alloc_msg(gss_auth, uid, gss_cred->gc_principal); 499 gss_new = gss_alloc_msg(gss_auth, uid, gss_cred->gc_principal);
497 if (IS_ERR(gss_new)) 500 if (IS_ERR(gss_new))
498 return gss_new; 501 return gss_new;
499 gss_msg = gss_add_msg(gss_new); 502 gss_msg = gss_add_msg(gss_new);
500 if (gss_msg == gss_new) { 503 if (gss_msg == gss_new) {
501 int res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg); 504 int res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg);
502 if (res) { 505 if (res) {
503 gss_unhash_msg(gss_new); 506 gss_unhash_msg(gss_new);
504 gss_msg = ERR_PTR(res); 507 gss_msg = ERR_PTR(res);
505 } 508 }
506 } else 509 } else
507 gss_release_msg(gss_new); 510 gss_release_msg(gss_new);
508 return gss_msg; 511 return gss_msg;
509 } 512 }
510 513
511 static void warn_gssd(void) 514 static void warn_gssd(void)
512 { 515 {
513 static unsigned long ratelimit; 516 static unsigned long ratelimit;
514 unsigned long now = jiffies; 517 unsigned long now = jiffies;
515 518
516 if (time_after(now, ratelimit)) { 519 if (time_after(now, ratelimit)) {
517 printk(KERN_WARNING "RPC: AUTH_GSS upcall timed out.\n" 520 printk(KERN_WARNING "RPC: AUTH_GSS upcall timed out.\n"
518 "Please check user daemon is running.\n"); 521 "Please check user daemon is running.\n");
519 ratelimit = now + 15*HZ; 522 ratelimit = now + 15*HZ;
520 } 523 }
521 } 524 }
522 525
523 static inline int 526 static inline int
524 gss_refresh_upcall(struct rpc_task *task) 527 gss_refresh_upcall(struct rpc_task *task)
525 { 528 {
526 struct rpc_cred *cred = task->tk_rqstp->rq_cred; 529 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
527 struct gss_auth *gss_auth = container_of(cred->cr_auth, 530 struct gss_auth *gss_auth = container_of(cred->cr_auth,
528 struct gss_auth, rpc_auth); 531 struct gss_auth, rpc_auth);
529 struct gss_cred *gss_cred = container_of(cred, 532 struct gss_cred *gss_cred = container_of(cred,
530 struct gss_cred, gc_base); 533 struct gss_cred, gc_base);
531 struct gss_upcall_msg *gss_msg; 534 struct gss_upcall_msg *gss_msg;
532 struct rpc_pipe *pipe; 535 struct rpc_pipe *pipe;
533 int err = 0; 536 int err = 0;
534 537
535 dprintk("RPC: %5u %s for uid %u\n", 538 dprintk("RPC: %5u %s for uid %u\n",
536 task->tk_pid, __func__, from_kuid(&init_user_ns, cred->cr_uid)); 539 task->tk_pid, __func__, from_kuid(&init_user_ns, cred->cr_uid));
537 gss_msg = gss_setup_upcall(gss_auth, cred); 540 gss_msg = gss_setup_upcall(gss_auth, cred);
538 if (PTR_ERR(gss_msg) == -EAGAIN) { 541 if (PTR_ERR(gss_msg) == -EAGAIN) {
539 /* XXX: warning on the first, under the assumption we 542 /* XXX: warning on the first, under the assumption we
540 * shouldn't normally hit this case on a refresh. */ 543 * shouldn't normally hit this case on a refresh. */
541 warn_gssd(); 544 warn_gssd();
542 task->tk_timeout = 15*HZ; 545 task->tk_timeout = 15*HZ;
543 rpc_sleep_on(&pipe_version_rpc_waitqueue, task, NULL); 546 rpc_sleep_on(&pipe_version_rpc_waitqueue, task, NULL);
544 return -EAGAIN; 547 return -EAGAIN;
545 } 548 }
546 if (IS_ERR(gss_msg)) { 549 if (IS_ERR(gss_msg)) {
547 err = PTR_ERR(gss_msg); 550 err = PTR_ERR(gss_msg);
548 goto out; 551 goto out;
549 } 552 }
550 pipe = gss_msg->pipe; 553 pipe = gss_msg->pipe;
551 spin_lock(&pipe->lock); 554 spin_lock(&pipe->lock);
552 if (gss_cred->gc_upcall != NULL) 555 if (gss_cred->gc_upcall != NULL)
553 rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL); 556 rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL);
554 else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) { 557 else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) {
555 task->tk_timeout = 0; 558 task->tk_timeout = 0;
556 gss_cred->gc_upcall = gss_msg; 559 gss_cred->gc_upcall = gss_msg;
557 /* gss_upcall_callback will release the reference to gss_upcall_msg */ 560 /* gss_upcall_callback will release the reference to gss_upcall_msg */
558 atomic_inc(&gss_msg->count); 561 atomic_inc(&gss_msg->count);
559 rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback); 562 rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback);
560 } else { 563 } else {
561 gss_handle_downcall_result(gss_cred, gss_msg); 564 gss_handle_downcall_result(gss_cred, gss_msg);
562 err = gss_msg->msg.errno; 565 err = gss_msg->msg.errno;
563 } 566 }
564 spin_unlock(&pipe->lock); 567 spin_unlock(&pipe->lock);
565 gss_release_msg(gss_msg); 568 gss_release_msg(gss_msg);
566 out: 569 out:
567 dprintk("RPC: %5u %s for uid %u result %d\n", 570 dprintk("RPC: %5u %s for uid %u result %d\n",
568 task->tk_pid, __func__, 571 task->tk_pid, __func__,
569 from_kuid(&init_user_ns, cred->cr_uid), err); 572 from_kuid(&init_user_ns, cred->cr_uid), err);
570 return err; 573 return err;
571 } 574 }
572 575
573 static inline int 576 static inline int
574 gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred) 577 gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
575 { 578 {
576 struct net *net = gss_auth->net; 579 struct net *net = gss_auth->net;
577 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 580 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
578 struct rpc_pipe *pipe; 581 struct rpc_pipe *pipe;
579 struct rpc_cred *cred = &gss_cred->gc_base; 582 struct rpc_cred *cred = &gss_cred->gc_base;
580 struct gss_upcall_msg *gss_msg; 583 struct gss_upcall_msg *gss_msg;
581 unsigned long timeout; 584 unsigned long timeout;
582 DEFINE_WAIT(wait); 585 DEFINE_WAIT(wait);
583 int err; 586 int err;
584 587
585 dprintk("RPC: %s for uid %u\n", 588 dprintk("RPC: %s for uid %u\n",
586 __func__, from_kuid(&init_user_ns, cred->cr_uid)); 589 __func__, from_kuid(&init_user_ns, cred->cr_uid));
587 retry: 590 retry:
588 err = 0; 591 err = 0;
589 /* Default timeout is 15s unless we know that gssd is not running */ 592 /* Default timeout is 15s unless we know that gssd is not running */
590 timeout = 15 * HZ; 593 timeout = 15 * HZ;
591 if (!sn->gssd_running) 594 if (!sn->gssd_running)
592 timeout = HZ >> 2; 595 timeout = HZ >> 2;
593 gss_msg = gss_setup_upcall(gss_auth, cred); 596 gss_msg = gss_setup_upcall(gss_auth, cred);
594 if (PTR_ERR(gss_msg) == -EAGAIN) { 597 if (PTR_ERR(gss_msg) == -EAGAIN) {
595 err = wait_event_interruptible_timeout(pipe_version_waitqueue, 598 err = wait_event_interruptible_timeout(pipe_version_waitqueue,
596 sn->pipe_version >= 0, timeout); 599 sn->pipe_version >= 0, timeout);
597 if (sn->pipe_version < 0) { 600 if (sn->pipe_version < 0) {
598 if (err == 0) 601 if (err == 0)
599 sn->gssd_running = 0; 602 sn->gssd_running = 0;
600 warn_gssd(); 603 warn_gssd();
601 err = -EACCES; 604 err = -EACCES;
602 } 605 }
603 if (err < 0) 606 if (err < 0)
604 goto out; 607 goto out;
605 goto retry; 608 goto retry;
606 } 609 }
607 if (IS_ERR(gss_msg)) { 610 if (IS_ERR(gss_msg)) {
608 err = PTR_ERR(gss_msg); 611 err = PTR_ERR(gss_msg);
609 goto out; 612 goto out;
610 } 613 }
611 pipe = gss_msg->pipe; 614 pipe = gss_msg->pipe;
612 for (;;) { 615 for (;;) {
613 prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_KILLABLE); 616 prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_KILLABLE);
614 spin_lock(&pipe->lock); 617 spin_lock(&pipe->lock);
615 if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) { 618 if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) {
616 break; 619 break;
617 } 620 }
618 spin_unlock(&pipe->lock); 621 spin_unlock(&pipe->lock);
619 if (fatal_signal_pending(current)) { 622 if (fatal_signal_pending(current)) {
620 err = -ERESTARTSYS; 623 err = -ERESTARTSYS;
621 goto out_intr; 624 goto out_intr;
622 } 625 }
623 schedule(); 626 schedule();
624 } 627 }
625 if (gss_msg->ctx) 628 if (gss_msg->ctx)
626 gss_cred_set_ctx(cred, gss_msg->ctx); 629 gss_cred_set_ctx(cred, gss_msg->ctx);
627 else 630 else
628 err = gss_msg->msg.errno; 631 err = gss_msg->msg.errno;
629 spin_unlock(&pipe->lock); 632 spin_unlock(&pipe->lock);
630 out_intr: 633 out_intr:
631 finish_wait(&gss_msg->waitqueue, &wait); 634 finish_wait(&gss_msg->waitqueue, &wait);
632 gss_release_msg(gss_msg); 635 gss_release_msg(gss_msg);
633 out: 636 out:
634 dprintk("RPC: %s for uid %u result %d\n", 637 dprintk("RPC: %s for uid %u result %d\n",
635 __func__, from_kuid(&init_user_ns, cred->cr_uid), err); 638 __func__, from_kuid(&init_user_ns, cred->cr_uid), err);
636 return err; 639 return err;
637 } 640 }
638 641
639 #define MSG_BUF_MAXSIZE 1024 642 #define MSG_BUF_MAXSIZE 1024
640 643
641 static ssize_t 644 static ssize_t
642 gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) 645 gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
643 { 646 {
644 const void *p, *end; 647 const void *p, *end;
645 void *buf; 648 void *buf;
646 struct gss_upcall_msg *gss_msg; 649 struct gss_upcall_msg *gss_msg;
647 struct rpc_pipe *pipe = RPC_I(file_inode(filp))->pipe; 650 struct rpc_pipe *pipe = RPC_I(file_inode(filp))->pipe;
648 struct gss_cl_ctx *ctx; 651 struct gss_cl_ctx *ctx;
649 uid_t id; 652 uid_t id;
650 kuid_t uid; 653 kuid_t uid;
651 ssize_t err = -EFBIG; 654 ssize_t err = -EFBIG;
652 655
653 if (mlen > MSG_BUF_MAXSIZE) 656 if (mlen > MSG_BUF_MAXSIZE)
654 goto out; 657 goto out;
655 err = -ENOMEM; 658 err = -ENOMEM;
656 buf = kmalloc(mlen, GFP_NOFS); 659 buf = kmalloc(mlen, GFP_NOFS);
657 if (!buf) 660 if (!buf)
658 goto out; 661 goto out;
659 662
660 err = -EFAULT; 663 err = -EFAULT;
661 if (copy_from_user(buf, src, mlen)) 664 if (copy_from_user(buf, src, mlen))
662 goto err; 665 goto err;
663 666
664 end = (const void *)((char *)buf + mlen); 667 end = (const void *)((char *)buf + mlen);
665 p = simple_get_bytes(buf, end, &id, sizeof(id)); 668 p = simple_get_bytes(buf, end, &id, sizeof(id));
666 if (IS_ERR(p)) { 669 if (IS_ERR(p)) {
667 err = PTR_ERR(p); 670 err = PTR_ERR(p);
668 goto err; 671 goto err;
669 } 672 }
670 673
671 uid = make_kuid(&init_user_ns, id); 674 uid = make_kuid(&init_user_ns, id);
672 if (!uid_valid(uid)) { 675 if (!uid_valid(uid)) {
673 err = -EINVAL; 676 err = -EINVAL;
674 goto err; 677 goto err;
675 } 678 }
676 679
677 err = -ENOMEM; 680 err = -ENOMEM;
678 ctx = gss_alloc_context(); 681 ctx = gss_alloc_context();
679 if (ctx == NULL) 682 if (ctx == NULL)
680 goto err; 683 goto err;
681 684
682 err = -ENOENT; 685 err = -ENOENT;
683 /* Find a matching upcall */ 686 /* Find a matching upcall */
684 spin_lock(&pipe->lock); 687 spin_lock(&pipe->lock);
685 gss_msg = __gss_find_upcall(pipe, uid); 688 gss_msg = __gss_find_upcall(pipe, uid);
686 if (gss_msg == NULL) { 689 if (gss_msg == NULL) {
687 spin_unlock(&pipe->lock); 690 spin_unlock(&pipe->lock);
688 goto err_put_ctx; 691 goto err_put_ctx;
689 } 692 }
690 list_del_init(&gss_msg->list); 693 list_del_init(&gss_msg->list);
691 spin_unlock(&pipe->lock); 694 spin_unlock(&pipe->lock);
692 695
693 p = gss_fill_context(p, end, ctx, gss_msg->auth->mech); 696 p = gss_fill_context(p, end, ctx, gss_msg->auth->mech);
694 if (IS_ERR(p)) { 697 if (IS_ERR(p)) {
695 err = PTR_ERR(p); 698 err = PTR_ERR(p);
696 switch (err) { 699 switch (err) {
697 case -EACCES: 700 case -EACCES:
698 case -EKEYEXPIRED: 701 case -EKEYEXPIRED:
699 gss_msg->msg.errno = err; 702 gss_msg->msg.errno = err;
700 err = mlen; 703 err = mlen;
701 break; 704 break;
702 case -EFAULT: 705 case -EFAULT:
703 case -ENOMEM: 706 case -ENOMEM:
704 case -EINVAL: 707 case -EINVAL:
705 case -ENOSYS: 708 case -ENOSYS:
706 gss_msg->msg.errno = -EAGAIN; 709 gss_msg->msg.errno = -EAGAIN;
707 break; 710 break;
708 default: 711 default:
709 printk(KERN_CRIT "%s: bad return from " 712 printk(KERN_CRIT "%s: bad return from "
710 "gss_fill_context: %zd\n", __func__, err); 713 "gss_fill_context: %zd\n", __func__, err);
711 BUG(); 714 BUG();
712 } 715 }
713 goto err_release_msg; 716 goto err_release_msg;
714 } 717 }
715 gss_msg->ctx = gss_get_ctx(ctx); 718 gss_msg->ctx = gss_get_ctx(ctx);
716 err = mlen; 719 err = mlen;
717 720
718 err_release_msg: 721 err_release_msg:
719 spin_lock(&pipe->lock); 722 spin_lock(&pipe->lock);
720 __gss_unhash_msg(gss_msg); 723 __gss_unhash_msg(gss_msg);
721 spin_unlock(&pipe->lock); 724 spin_unlock(&pipe->lock);
722 gss_release_msg(gss_msg); 725 gss_release_msg(gss_msg);
723 err_put_ctx: 726 err_put_ctx:
724 gss_put_ctx(ctx); 727 gss_put_ctx(ctx);
725 err: 728 err:
726 kfree(buf); 729 kfree(buf);
727 out: 730 out:
728 dprintk("RPC: %s returning %Zd\n", __func__, err); 731 dprintk("RPC: %s returning %Zd\n", __func__, err);
729 return err; 732 return err;
730 } 733 }
731 734
732 static int gss_pipe_open(struct inode *inode, int new_version) 735 static int gss_pipe_open(struct inode *inode, int new_version)
733 { 736 {
734 struct net *net = inode->i_sb->s_fs_info; 737 struct net *net = inode->i_sb->s_fs_info;
735 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); 738 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
736 int ret = 0; 739 int ret = 0;
737 740
738 spin_lock(&pipe_version_lock); 741 spin_lock(&pipe_version_lock);
739 if (sn->pipe_version < 0) { 742 if (sn->pipe_version < 0) {
740 /* First open of any gss pipe determines the version: */ 743 /* First open of any gss pipe determines the version: */
741 sn->pipe_version = new_version; 744 sn->pipe_version = new_version;
742 rpc_wake_up(&pipe_version_rpc_waitqueue); 745 rpc_wake_up(&pipe_version_rpc_waitqueue);
743 wake_up(&pipe_version_waitqueue); 746 wake_up(&pipe_version_waitqueue);
744 } else if (sn->pipe_version != new_version) { 747 } else if (sn->pipe_version != new_version) {
745 /* Trying to open a pipe of a different version */ 748 /* Trying to open a pipe of a different version */
746 ret = -EBUSY; 749 ret = -EBUSY;
747 goto out; 750 goto out;
748 } 751 }
749 atomic_inc(&sn->pipe_users); 752 atomic_inc(&sn->pipe_users);
750 out: 753 out:
751 spin_unlock(&pipe_version_lock); 754 spin_unlock(&pipe_version_lock);
752 return ret; 755 return ret;
753 756
754 } 757 }
755 758
756 static int gss_pipe_open_v0(struct inode *inode) 759 static int gss_pipe_open_v0(struct inode *inode)
757 { 760 {
758 return gss_pipe_open(inode, 0); 761 return gss_pipe_open(inode, 0);
759 } 762 }
760 763
761 static int gss_pipe_open_v1(struct inode *inode) 764 static int gss_pipe_open_v1(struct inode *inode)
762 { 765 {
763 return gss_pipe_open(inode, 1); 766 return gss_pipe_open(inode, 1);
764 } 767 }
765 768
766 static void 769 static void
767 gss_pipe_release(struct inode *inode) 770 gss_pipe_release(struct inode *inode)
768 { 771 {
769 struct net *net = inode->i_sb->s_fs_info; 772 struct net *net = inode->i_sb->s_fs_info;
770 struct rpc_pipe *pipe = RPC_I(inode)->pipe; 773 struct rpc_pipe *pipe = RPC_I(inode)->pipe;
771 struct gss_upcall_msg *gss_msg; 774 struct gss_upcall_msg *gss_msg;
772 775
773 restart: 776 restart:
774 spin_lock(&pipe->lock); 777 spin_lock(&pipe->lock);
775 list_for_each_entry(gss_msg, &pipe->in_downcall, list) { 778 list_for_each_entry(gss_msg, &pipe->in_downcall, list) {
776 779
777 if (!list_empty(&gss_msg->msg.list)) 780 if (!list_empty(&gss_msg->msg.list))
778 continue; 781 continue;
779 gss_msg->msg.errno = -EPIPE; 782 gss_msg->msg.errno = -EPIPE;
780 atomic_inc(&gss_msg->count); 783 atomic_inc(&gss_msg->count);
781 __gss_unhash_msg(gss_msg); 784 __gss_unhash_msg(gss_msg);
782 spin_unlock(&pipe->lock); 785 spin_unlock(&pipe->lock);
783 gss_release_msg(gss_msg); 786 gss_release_msg(gss_msg);
784 goto restart; 787 goto restart;
785 } 788 }
786 spin_unlock(&pipe->lock); 789 spin_unlock(&pipe->lock);
787 790
788 put_pipe_version(net); 791 put_pipe_version(net);
789 } 792 }
790 793
791 static void 794 static void
792 gss_pipe_destroy_msg(struct rpc_pipe_msg *msg) 795 gss_pipe_destroy_msg(struct rpc_pipe_msg *msg)
793 { 796 {
794 struct gss_upcall_msg *gss_msg = container_of(msg, struct gss_upcall_msg, msg); 797 struct gss_upcall_msg *gss_msg = container_of(msg, struct gss_upcall_msg, msg);
795 798
796 if (msg->errno < 0) { 799 if (msg->errno < 0) {
797 dprintk("RPC: %s releasing msg %p\n", 800 dprintk("RPC: %s releasing msg %p\n",
798 __func__, gss_msg); 801 __func__, gss_msg);
799 atomic_inc(&gss_msg->count); 802 atomic_inc(&gss_msg->count);
800 gss_unhash_msg(gss_msg); 803 gss_unhash_msg(gss_msg);
801 if (msg->errno == -ETIMEDOUT) 804 if (msg->errno == -ETIMEDOUT)
802 warn_gssd(); 805 warn_gssd();
803 gss_release_msg(gss_msg); 806 gss_release_msg(gss_msg);
804 } 807 }
805 } 808 }
806 809
807 static void gss_pipe_dentry_destroy(struct dentry *dir, 810 static void gss_pipe_dentry_destroy(struct dentry *dir,
808 struct rpc_pipe_dir_object *pdo) 811 struct rpc_pipe_dir_object *pdo)
809 { 812 {
810 struct gss_pipe *gss_pipe = pdo->pdo_data; 813 struct gss_pipe *gss_pipe = pdo->pdo_data;
811 struct rpc_pipe *pipe = gss_pipe->pipe; 814 struct rpc_pipe *pipe = gss_pipe->pipe;
812 815
813 if (pipe->dentry != NULL) { 816 if (pipe->dentry != NULL) {
814 rpc_unlink(pipe->dentry); 817 rpc_unlink(pipe->dentry);
815 pipe->dentry = NULL; 818 pipe->dentry = NULL;
816 } 819 }
817 } 820 }
818 821
819 static int gss_pipe_dentry_create(struct dentry *dir, 822 static int gss_pipe_dentry_create(struct dentry *dir,
820 struct rpc_pipe_dir_object *pdo) 823 struct rpc_pipe_dir_object *pdo)
821 { 824 {
822 struct gss_pipe *p = pdo->pdo_data; 825 struct gss_pipe *p = pdo->pdo_data;
823 struct dentry *dentry; 826 struct dentry *dentry;
824 827
825 dentry = rpc_mkpipe_dentry(dir, p->name, p->clnt, p->pipe); 828 dentry = rpc_mkpipe_dentry(dir, p->name, p->clnt, p->pipe);
826 if (IS_ERR(dentry)) 829 if (IS_ERR(dentry))
827 return PTR_ERR(dentry); 830 return PTR_ERR(dentry);
828 p->pipe->dentry = dentry; 831 p->pipe->dentry = dentry;
829 return 0; 832 return 0;
830 } 833 }
831 834
832 static const struct rpc_pipe_dir_object_ops gss_pipe_dir_object_ops = { 835 static const struct rpc_pipe_dir_object_ops gss_pipe_dir_object_ops = {
833 .create = gss_pipe_dentry_create, 836 .create = gss_pipe_dentry_create,
834 .destroy = gss_pipe_dentry_destroy, 837 .destroy = gss_pipe_dentry_destroy,
835 }; 838 };
836 839
837 static struct gss_pipe *gss_pipe_alloc(struct rpc_clnt *clnt, 840 static struct gss_pipe *gss_pipe_alloc(struct rpc_clnt *clnt,
838 const char *name, 841 const char *name,
839 const struct rpc_pipe_ops *upcall_ops) 842 const struct rpc_pipe_ops *upcall_ops)
840 { 843 {
841 struct gss_pipe *p; 844 struct gss_pipe *p;
842 int err = -ENOMEM; 845 int err = -ENOMEM;
843 846
844 p = kmalloc(sizeof(*p), GFP_KERNEL); 847 p = kmalloc(sizeof(*p), GFP_KERNEL);
845 if (p == NULL) 848 if (p == NULL)
846 goto err; 849 goto err;
847 p->pipe = rpc_mkpipe_data(upcall_ops, RPC_PIPE_WAIT_FOR_OPEN); 850 p->pipe = rpc_mkpipe_data(upcall_ops, RPC_PIPE_WAIT_FOR_OPEN);
848 if (IS_ERR(p->pipe)) { 851 if (IS_ERR(p->pipe)) {
849 err = PTR_ERR(p->pipe); 852 err = PTR_ERR(p->pipe);
850 goto err_free_gss_pipe; 853 goto err_free_gss_pipe;
851 } 854 }
852 p->name = name; 855 p->name = name;
853 p->clnt = clnt; 856 p->clnt = clnt;
854 kref_init(&p->kref); 857 kref_init(&p->kref);
855 rpc_init_pipe_dir_object(&p->pdo, 858 rpc_init_pipe_dir_object(&p->pdo,
856 &gss_pipe_dir_object_ops, 859 &gss_pipe_dir_object_ops,
857 p); 860 p);
858 return p; 861 return p;
859 err_free_gss_pipe: 862 err_free_gss_pipe:
860 kfree(p); 863 kfree(p);
861 err: 864 err:
862 return ERR_PTR(err); 865 return ERR_PTR(err);
863 } 866 }
864 867
865 struct gss_alloc_pdo { 868 struct gss_alloc_pdo {
866 struct rpc_clnt *clnt; 869 struct rpc_clnt *clnt;
867 const char *name; 870 const char *name;
868 const struct rpc_pipe_ops *upcall_ops; 871 const struct rpc_pipe_ops *upcall_ops;
869 }; 872 };
870 873
871 static int gss_pipe_match_pdo(struct rpc_pipe_dir_object *pdo, void *data) 874 static int gss_pipe_match_pdo(struct rpc_pipe_dir_object *pdo, void *data)
872 { 875 {
873 struct gss_pipe *gss_pipe; 876 struct gss_pipe *gss_pipe;
874 struct gss_alloc_pdo *args = data; 877 struct gss_alloc_pdo *args = data;
875 878
876 if (pdo->pdo_ops != &gss_pipe_dir_object_ops) 879 if (pdo->pdo_ops != &gss_pipe_dir_object_ops)
877 return 0; 880 return 0;
878 gss_pipe = container_of(pdo, struct gss_pipe, pdo); 881 gss_pipe = container_of(pdo, struct gss_pipe, pdo);
879 if (strcmp(gss_pipe->name, args->name) != 0) 882 if (strcmp(gss_pipe->name, args->name) != 0)
880 return 0; 883 return 0;
881 if (!kref_get_unless_zero(&gss_pipe->kref)) 884 if (!kref_get_unless_zero(&gss_pipe->kref))
882 return 0; 885 return 0;
883 return 1; 886 return 1;
884 } 887 }
885 888
886 static struct rpc_pipe_dir_object *gss_pipe_alloc_pdo(void *data) 889 static struct rpc_pipe_dir_object *gss_pipe_alloc_pdo(void *data)
887 { 890 {
888 struct gss_pipe *gss_pipe; 891 struct gss_pipe *gss_pipe;
889 struct gss_alloc_pdo *args = data; 892 struct gss_alloc_pdo *args = data;
890 893
891 gss_pipe = gss_pipe_alloc(args->clnt, args->name, args->upcall_ops); 894 gss_pipe = gss_pipe_alloc(args->clnt, args->name, args->upcall_ops);
892 if (!IS_ERR(gss_pipe)) 895 if (!IS_ERR(gss_pipe))
893 return &gss_pipe->pdo; 896 return &gss_pipe->pdo;
894 return NULL; 897 return NULL;
895 } 898 }
896 899
897 static struct gss_pipe *gss_pipe_get(struct rpc_clnt *clnt, 900 static struct gss_pipe *gss_pipe_get(struct rpc_clnt *clnt,
898 const char *name, 901 const char *name,
899 const struct rpc_pipe_ops *upcall_ops) 902 const struct rpc_pipe_ops *upcall_ops)
900 { 903 {
901 struct net *net = rpc_net_ns(clnt); 904 struct net *net = rpc_net_ns(clnt);
902 struct rpc_pipe_dir_object *pdo; 905 struct rpc_pipe_dir_object *pdo;
903 struct gss_alloc_pdo args = { 906 struct gss_alloc_pdo args = {
904 .clnt = clnt, 907 .clnt = clnt,
905 .name = name, 908 .name = name,
906 .upcall_ops = upcall_ops, 909 .upcall_ops = upcall_ops,
907 }; 910 };
908 911
909 pdo = rpc_find_or_alloc_pipe_dir_object(net, 912 pdo = rpc_find_or_alloc_pipe_dir_object(net,
910 &clnt->cl_pipedir_objects, 913 &clnt->cl_pipedir_objects,
911 gss_pipe_match_pdo, 914 gss_pipe_match_pdo,
912 gss_pipe_alloc_pdo, 915 gss_pipe_alloc_pdo,
913 &args); 916 &args);
914 if (pdo != NULL) 917 if (pdo != NULL)
915 return container_of(pdo, struct gss_pipe, pdo); 918 return container_of(pdo, struct gss_pipe, pdo);
916 return ERR_PTR(-ENOMEM); 919 return ERR_PTR(-ENOMEM);
917 } 920 }
918 921
919 static void __gss_pipe_free(struct gss_pipe *p) 922 static void __gss_pipe_free(struct gss_pipe *p)
920 { 923 {
921 struct rpc_clnt *clnt = p->clnt; 924 struct rpc_clnt *clnt = p->clnt;
922 struct net *net = rpc_net_ns(clnt); 925 struct net *net = rpc_net_ns(clnt);
923 926
924 rpc_remove_pipe_dir_object(net, 927 rpc_remove_pipe_dir_object(net,
925 &clnt->cl_pipedir_objects, 928 &clnt->cl_pipedir_objects,
926 &p->pdo); 929 &p->pdo);
927 rpc_destroy_pipe_data(p->pipe); 930 rpc_destroy_pipe_data(p->pipe);
928 kfree(p); 931 kfree(p);
929 } 932 }
930 933
931 static void __gss_pipe_release(struct kref *kref) 934 static void __gss_pipe_release(struct kref *kref)
932 { 935 {
933 struct gss_pipe *p = container_of(kref, struct gss_pipe, kref); 936 struct gss_pipe *p = container_of(kref, struct gss_pipe, kref);
934 937
935 __gss_pipe_free(p); 938 __gss_pipe_free(p);
936 } 939 }
937 940
938 static void gss_pipe_free(struct gss_pipe *p) 941 static void gss_pipe_free(struct gss_pipe *p)
939 { 942 {
940 if (p != NULL) 943 if (p != NULL)
941 kref_put(&p->kref, __gss_pipe_release); 944 kref_put(&p->kref, __gss_pipe_release);
942 } 945 }
943 946
944 /* 947 /*
945 * NOTE: we have the opportunity to use different 948 * NOTE: we have the opportunity to use different
946 * parameters based on the input flavor (which must be a pseudoflavor) 949 * parameters based on the input flavor (which must be a pseudoflavor)
947 */ 950 */
948 static struct gss_auth * 951 static struct gss_auth *
949 gss_create_new(struct rpc_auth_create_args *args, struct rpc_clnt *clnt) 952 gss_create_new(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
950 { 953 {
951 rpc_authflavor_t flavor = args->pseudoflavor; 954 rpc_authflavor_t flavor = args->pseudoflavor;
952 struct gss_auth *gss_auth; 955 struct gss_auth *gss_auth;
953 struct gss_pipe *gss_pipe; 956 struct gss_pipe *gss_pipe;
954 struct rpc_auth * auth; 957 struct rpc_auth * auth;
955 int err = -ENOMEM; /* XXX? */ 958 int err = -ENOMEM; /* XXX? */
956 959
957 dprintk("RPC: creating GSS authenticator for client %p\n", clnt); 960 dprintk("RPC: creating GSS authenticator for client %p\n", clnt);
958 961
959 if (!try_module_get(THIS_MODULE)) 962 if (!try_module_get(THIS_MODULE))
960 return ERR_PTR(err); 963 return ERR_PTR(err);
961 if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL))) 964 if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL)))
962 goto out_dec; 965 goto out_dec;
963 INIT_HLIST_NODE(&gss_auth->hash); 966 INIT_HLIST_NODE(&gss_auth->hash);
964 gss_auth->target_name = NULL; 967 gss_auth->target_name = NULL;
965 if (args->target_name) { 968 if (args->target_name) {
966 gss_auth->target_name = kstrdup(args->target_name, GFP_KERNEL); 969 gss_auth->target_name = kstrdup(args->target_name, GFP_KERNEL);
967 if (gss_auth->target_name == NULL) 970 if (gss_auth->target_name == NULL)
968 goto err_free; 971 goto err_free;
969 } 972 }
970 gss_auth->client = clnt; 973 gss_auth->client = clnt;
971 gss_auth->net = get_net(rpc_net_ns(clnt)); 974 gss_auth->net = get_net(rpc_net_ns(clnt));
972 err = -EINVAL; 975 err = -EINVAL;
973 gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor); 976 gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor);
974 if (!gss_auth->mech) { 977 if (!gss_auth->mech) {
975 dprintk("RPC: Pseudoflavor %d not found!\n", flavor); 978 dprintk("RPC: Pseudoflavor %d not found!\n", flavor);
976 goto err_put_net; 979 goto err_put_net;
977 } 980 }
978 gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor); 981 gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor);
979 if (gss_auth->service == 0) 982 if (gss_auth->service == 0)
980 goto err_put_mech; 983 goto err_put_mech;
981 auth = &gss_auth->rpc_auth; 984 auth = &gss_auth->rpc_auth;
982 auth->au_cslack = GSS_CRED_SLACK >> 2; 985 auth->au_cslack = GSS_CRED_SLACK >> 2;
983 auth->au_rslack = GSS_VERF_SLACK >> 2; 986 auth->au_rslack = GSS_VERF_SLACK >> 2;
984 auth->au_ops = &authgss_ops; 987 auth->au_ops = &authgss_ops;
985 auth->au_flavor = flavor; 988 auth->au_flavor = flavor;
986 atomic_set(&auth->au_count, 1); 989 atomic_set(&auth->au_count, 1);
987 kref_init(&gss_auth->kref); 990 kref_init(&gss_auth->kref);
988 991
989 err = rpcauth_init_credcache(auth); 992 err = rpcauth_init_credcache(auth);
990 if (err) 993 if (err)
991 goto err_put_mech; 994 goto err_put_mech;
992 /* 995 /*
993 * Note: if we created the old pipe first, then someone who 996 * Note: if we created the old pipe first, then someone who
994 * examined the directory at the right moment might conclude 997 * examined the directory at the right moment might conclude
995 * that we supported only the old pipe. So we instead create 998 * that we supported only the old pipe. So we instead create
996 * the new pipe first. 999 * the new pipe first.
997 */ 1000 */
998 gss_pipe = gss_pipe_get(clnt, "gssd", &gss_upcall_ops_v1); 1001 gss_pipe = gss_pipe_get(clnt, "gssd", &gss_upcall_ops_v1);
999 if (IS_ERR(gss_pipe)) { 1002 if (IS_ERR(gss_pipe)) {
1000 err = PTR_ERR(gss_pipe); 1003 err = PTR_ERR(gss_pipe);
1001 goto err_destroy_credcache; 1004 goto err_destroy_credcache;
1002 } 1005 }
1003 gss_auth->gss_pipe[1] = gss_pipe; 1006 gss_auth->gss_pipe[1] = gss_pipe;
1004 1007
1005 gss_pipe = gss_pipe_get(clnt, gss_auth->mech->gm_name, 1008 gss_pipe = gss_pipe_get(clnt, gss_auth->mech->gm_name,
1006 &gss_upcall_ops_v0); 1009 &gss_upcall_ops_v0);
1007 if (IS_ERR(gss_pipe)) { 1010 if (IS_ERR(gss_pipe)) {
1008 err = PTR_ERR(gss_pipe); 1011 err = PTR_ERR(gss_pipe);
1009 goto err_destroy_pipe_1; 1012 goto err_destroy_pipe_1;
1010 } 1013 }
1011 gss_auth->gss_pipe[0] = gss_pipe; 1014 gss_auth->gss_pipe[0] = gss_pipe;
1012 1015
1013 return gss_auth; 1016 return gss_auth;
1014 err_destroy_pipe_1: 1017 err_destroy_pipe_1:
1015 gss_pipe_free(gss_auth->gss_pipe[1]); 1018 gss_pipe_free(gss_auth->gss_pipe[1]);
1016 err_destroy_credcache: 1019 err_destroy_credcache:
1017 rpcauth_destroy_credcache(auth); 1020 rpcauth_destroy_credcache(auth);
1018 err_put_mech: 1021 err_put_mech:
1019 gss_mech_put(gss_auth->mech); 1022 gss_mech_put(gss_auth->mech);
1020 err_put_net: 1023 err_put_net:
1021 put_net(gss_auth->net); 1024 put_net(gss_auth->net);
1022 err_free: 1025 err_free:
1023 kfree(gss_auth->target_name); 1026 kfree(gss_auth->target_name);
1024 kfree(gss_auth); 1027 kfree(gss_auth);
1025 out_dec: 1028 out_dec:
1026 module_put(THIS_MODULE); 1029 module_put(THIS_MODULE);
1027 return ERR_PTR(err); 1030 return ERR_PTR(err);
1028 } 1031 }
1029 1032
1030 static void 1033 static void
1031 gss_free(struct gss_auth *gss_auth) 1034 gss_free(struct gss_auth *gss_auth)
1032 { 1035 {
1033 gss_pipe_free(gss_auth->gss_pipe[0]); 1036 gss_pipe_free(gss_auth->gss_pipe[0]);
1034 gss_pipe_free(gss_auth->gss_pipe[1]); 1037 gss_pipe_free(gss_auth->gss_pipe[1]);
1035 gss_mech_put(gss_auth->mech); 1038 gss_mech_put(gss_auth->mech);
1036 put_net(gss_auth->net); 1039 put_net(gss_auth->net);
1037 kfree(gss_auth->target_name); 1040 kfree(gss_auth->target_name);
1038 1041
1039 kfree(gss_auth); 1042 kfree(gss_auth);
1040 module_put(THIS_MODULE); 1043 module_put(THIS_MODULE);
1041 } 1044 }
1042 1045
1043 static void 1046 static void
1044 gss_free_callback(struct kref *kref) 1047 gss_free_callback(struct kref *kref)
1045 { 1048 {
1046 struct gss_auth *gss_auth = container_of(kref, struct gss_auth, kref); 1049 struct gss_auth *gss_auth = container_of(kref, struct gss_auth, kref);
1047 1050
1048 gss_free(gss_auth); 1051 gss_free(gss_auth);
1049 } 1052 }
1050 1053
1051 static void 1054 static void
1052 gss_destroy(struct rpc_auth *auth) 1055 gss_destroy(struct rpc_auth *auth)
1053 { 1056 {
1054 struct gss_auth *gss_auth = container_of(auth, 1057 struct gss_auth *gss_auth = container_of(auth,
1055 struct gss_auth, rpc_auth); 1058 struct gss_auth, rpc_auth);
1056 1059
1057 dprintk("RPC: destroying GSS authenticator %p flavor %d\n", 1060 dprintk("RPC: destroying GSS authenticator %p flavor %d\n",
1058 auth, auth->au_flavor); 1061 auth, auth->au_flavor);
1059 1062
1060 if (hash_hashed(&gss_auth->hash)) { 1063 if (hash_hashed(&gss_auth->hash)) {
1061 spin_lock(&gss_auth_hash_lock); 1064 spin_lock(&gss_auth_hash_lock);
1062 hash_del(&gss_auth->hash); 1065 hash_del(&gss_auth->hash);
1063 spin_unlock(&gss_auth_hash_lock); 1066 spin_unlock(&gss_auth_hash_lock);
1064 } 1067 }
1065 1068
1066 gss_pipe_free(gss_auth->gss_pipe[0]); 1069 gss_pipe_free(gss_auth->gss_pipe[0]);
1067 gss_auth->gss_pipe[0] = NULL; 1070 gss_auth->gss_pipe[0] = NULL;
1068 gss_pipe_free(gss_auth->gss_pipe[1]); 1071 gss_pipe_free(gss_auth->gss_pipe[1]);
1069 gss_auth->gss_pipe[1] = NULL; 1072 gss_auth->gss_pipe[1] = NULL;
1070 rpcauth_destroy_credcache(auth); 1073 rpcauth_destroy_credcache(auth);
1071 1074
1072 kref_put(&gss_auth->kref, gss_free_callback); 1075 kref_put(&gss_auth->kref, gss_free_callback);
1073 } 1076 }
1074 1077
1075 static struct gss_auth * 1078 static struct gss_auth *
1076 gss_auth_find_or_add_hashed(struct rpc_auth_create_args *args, 1079 gss_auth_find_or_add_hashed(struct rpc_auth_create_args *args,
1077 struct rpc_clnt *clnt, 1080 struct rpc_clnt *clnt,
1078 struct gss_auth *new) 1081 struct gss_auth *new)
1079 { 1082 {
1080 struct gss_auth *gss_auth; 1083 struct gss_auth *gss_auth;
1081 unsigned long hashval = (unsigned long)clnt; 1084 unsigned long hashval = (unsigned long)clnt;
1082 1085
1083 spin_lock(&gss_auth_hash_lock); 1086 spin_lock(&gss_auth_hash_lock);
1084 hash_for_each_possible(gss_auth_hash_table, 1087 hash_for_each_possible(gss_auth_hash_table,
1085 gss_auth, 1088 gss_auth,
1086 hash, 1089 hash,
1087 hashval) { 1090 hashval) {
1088 if (gss_auth->rpc_auth.au_flavor != args->pseudoflavor) 1091 if (gss_auth->rpc_auth.au_flavor != args->pseudoflavor)
1089 continue; 1092 continue;
1090 if (gss_auth->target_name != args->target_name) { 1093 if (gss_auth->target_name != args->target_name) {
1091 if (gss_auth->target_name == NULL) 1094 if (gss_auth->target_name == NULL)
1092 continue; 1095 continue;
1093 if (args->target_name == NULL) 1096 if (args->target_name == NULL)
1094 continue; 1097 continue;
1095 if (strcmp(gss_auth->target_name, args->target_name)) 1098 if (strcmp(gss_auth->target_name, args->target_name))
1096 continue; 1099 continue;
1097 } 1100 }
1098 if (!atomic_inc_not_zero(&gss_auth->rpc_auth.au_count)) 1101 if (!atomic_inc_not_zero(&gss_auth->rpc_auth.au_count))
1099 continue; 1102 continue;
1100 goto out; 1103 goto out;
1101 } 1104 }
1102 if (new) 1105 if (new)
1103 hash_add(gss_auth_hash_table, &new->hash, hashval); 1106 hash_add(gss_auth_hash_table, &new->hash, hashval);
1104 gss_auth = new; 1107 gss_auth = new;
1105 out: 1108 out:
1106 spin_unlock(&gss_auth_hash_lock); 1109 spin_unlock(&gss_auth_hash_lock);
1107 return gss_auth; 1110 return gss_auth;
1108 } 1111 }
1109 1112
1110 static struct gss_auth * 1113 static struct gss_auth *
1111 gss_create_hashed(struct rpc_auth_create_args *args, struct rpc_clnt *clnt) 1114 gss_create_hashed(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
1112 { 1115 {
1113 struct gss_auth *gss_auth; 1116 struct gss_auth *gss_auth;
1114 struct gss_auth *new; 1117 struct gss_auth *new;
1115 1118
1116 gss_auth = gss_auth_find_or_add_hashed(args, clnt, NULL); 1119 gss_auth = gss_auth_find_or_add_hashed(args, clnt, NULL);
1117 if (gss_auth != NULL) 1120 if (gss_auth != NULL)
1118 goto out; 1121 goto out;
1119 new = gss_create_new(args, clnt); 1122 new = gss_create_new(args, clnt);
1120 if (IS_ERR(new)) 1123 if (IS_ERR(new))
1121 return new; 1124 return new;
1122 gss_auth = gss_auth_find_or_add_hashed(args, clnt, new); 1125 gss_auth = gss_auth_find_or_add_hashed(args, clnt, new);
1123 if (gss_auth != new) 1126 if (gss_auth != new)
1124 gss_destroy(&new->rpc_auth); 1127 gss_destroy(&new->rpc_auth);
1125 out: 1128 out:
1126 return gss_auth; 1129 return gss_auth;
1127 } 1130 }
1128 1131
1129 static struct rpc_auth * 1132 static struct rpc_auth *
1130 gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt) 1133 gss_create(struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
1131 { 1134 {
1132 struct gss_auth *gss_auth; 1135 struct gss_auth *gss_auth;
1133 struct rpc_xprt *xprt = rcu_access_pointer(clnt->cl_xprt); 1136 struct rpc_xprt *xprt = rcu_access_pointer(clnt->cl_xprt);
1134 1137
1135 while (clnt != clnt->cl_parent) { 1138 while (clnt != clnt->cl_parent) {
1136 struct rpc_clnt *parent = clnt->cl_parent; 1139 struct rpc_clnt *parent = clnt->cl_parent;
1137 /* Find the original parent for this transport */ 1140 /* Find the original parent for this transport */
1138 if (rcu_access_pointer(parent->cl_xprt) != xprt) 1141 if (rcu_access_pointer(parent->cl_xprt) != xprt)
1139 break; 1142 break;
1140 clnt = parent; 1143 clnt = parent;
1141 } 1144 }
1142 1145
1143 gss_auth = gss_create_hashed(args, clnt); 1146 gss_auth = gss_create_hashed(args, clnt);
1144 if (IS_ERR(gss_auth)) 1147 if (IS_ERR(gss_auth))
1145 return ERR_CAST(gss_auth); 1148 return ERR_CAST(gss_auth);
1146 return &gss_auth->rpc_auth; 1149 return &gss_auth->rpc_auth;
1147 } 1150 }
1148 1151
1149 /* 1152 /*
1150 * gss_destroying_context will cause the RPCSEC_GSS to send a NULL RPC call 1153 * gss_destroying_context will cause the RPCSEC_GSS to send a NULL RPC call
1151 * to the server with the GSS control procedure field set to 1154 * to the server with the GSS control procedure field set to
1152 * RPC_GSS_PROC_DESTROY. This should normally cause the server to release 1155 * RPC_GSS_PROC_DESTROY. This should normally cause the server to release
1153 * all RPCSEC_GSS state associated with that context. 1156 * all RPCSEC_GSS state associated with that context.
1154 */ 1157 */
1155 static int 1158 static int
1156 gss_destroying_context(struct rpc_cred *cred) 1159 gss_destroying_context(struct rpc_cred *cred)
1157 { 1160 {
1158 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base); 1161 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
1159 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth); 1162 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth);
1160 struct rpc_task *task; 1163 struct rpc_task *task;
1161 1164
1162 if (gss_cred->gc_ctx == NULL || 1165 if (gss_cred->gc_ctx == NULL ||
1163 test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0) 1166 test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0)
1164 return 0; 1167 return 0;
1165 1168
1166 gss_cred->gc_ctx->gc_proc = RPC_GSS_PROC_DESTROY; 1169 gss_cred->gc_ctx->gc_proc = RPC_GSS_PROC_DESTROY;
1167 cred->cr_ops = &gss_nullops; 1170 cred->cr_ops = &gss_nullops;
1168 1171
1169 /* Take a reference to ensure the cred will be destroyed either 1172 /* Take a reference to ensure the cred will be destroyed either
1170 * by the RPC call or by the put_rpccred() below */ 1173 * by the RPC call or by the put_rpccred() below */
1171 get_rpccred(cred); 1174 get_rpccred(cred);
1172 1175
1173 task = rpc_call_null(gss_auth->client, cred, RPC_TASK_ASYNC|RPC_TASK_SOFT); 1176 task = rpc_call_null(gss_auth->client, cred, RPC_TASK_ASYNC|RPC_TASK_SOFT);
1174 if (!IS_ERR(task)) 1177 if (!IS_ERR(task))
1175 rpc_put_task(task); 1178 rpc_put_task(task);
1176 1179
1177 put_rpccred(cred); 1180 put_rpccred(cred);
1178 return 1; 1181 return 1;
1179 } 1182 }
1180 1183
1181 /* gss_destroy_cred (and gss_free_ctx) are used to clean up after failure 1184 /* gss_destroy_cred (and gss_free_ctx) are used to clean up after failure
1182 * to create a new cred or context, so they check that things have been 1185 * to create a new cred or context, so they check that things have been
1183 * allocated before freeing them. */ 1186 * allocated before freeing them. */
1184 static void 1187 static void
1185 gss_do_free_ctx(struct gss_cl_ctx *ctx) 1188 gss_do_free_ctx(struct gss_cl_ctx *ctx)
1186 { 1189 {
1187 dprintk("RPC: %s\n", __func__); 1190 dprintk("RPC: %s\n", __func__);
1188 1191
1189 gss_delete_sec_context(&ctx->gc_gss_ctx); 1192 gss_delete_sec_context(&ctx->gc_gss_ctx);
1190 kfree(ctx->gc_wire_ctx.data); 1193 kfree(ctx->gc_wire_ctx.data);
1191 kfree(ctx); 1194 kfree(ctx);
1192 } 1195 }
1193 1196
1194 static void 1197 static void
1195 gss_free_ctx_callback(struct rcu_head *head) 1198 gss_free_ctx_callback(struct rcu_head *head)
1196 { 1199 {
1197 struct gss_cl_ctx *ctx = container_of(head, struct gss_cl_ctx, gc_rcu); 1200 struct gss_cl_ctx *ctx = container_of(head, struct gss_cl_ctx, gc_rcu);
1198 gss_do_free_ctx(ctx); 1201 gss_do_free_ctx(ctx);
1199 } 1202 }
1200 1203
1201 static void 1204 static void
1202 gss_free_ctx(struct gss_cl_ctx *ctx) 1205 gss_free_ctx(struct gss_cl_ctx *ctx)
1203 { 1206 {
1204 call_rcu(&ctx->gc_rcu, gss_free_ctx_callback); 1207 call_rcu(&ctx->gc_rcu, gss_free_ctx_callback);
1205 } 1208 }
1206 1209
1207 static void 1210 static void
1208 gss_free_cred(struct gss_cred *gss_cred) 1211 gss_free_cred(struct gss_cred *gss_cred)
1209 { 1212 {
1210 dprintk("RPC: %s cred=%p\n", __func__, gss_cred); 1213 dprintk("RPC: %s cred=%p\n", __func__, gss_cred);
1211 kfree(gss_cred); 1214 kfree(gss_cred);
1212 } 1215 }
1213 1216
1214 static void 1217 static void
1215 gss_free_cred_callback(struct rcu_head *head) 1218 gss_free_cred_callback(struct rcu_head *head)
1216 { 1219 {
1217 struct gss_cred *gss_cred = container_of(head, struct gss_cred, gc_base.cr_rcu); 1220 struct gss_cred *gss_cred = container_of(head, struct gss_cred, gc_base.cr_rcu);
1218 gss_free_cred(gss_cred); 1221 gss_free_cred(gss_cred);
1219 } 1222 }
1220 1223
1221 static void 1224 static void
1222 gss_destroy_nullcred(struct rpc_cred *cred) 1225 gss_destroy_nullcred(struct rpc_cred *cred)
1223 { 1226 {
1224 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base); 1227 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
1225 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth); 1228 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth);
1226 struct gss_cl_ctx *ctx = gss_cred->gc_ctx; 1229 struct gss_cl_ctx *ctx = gss_cred->gc_ctx;
1227 1230
1228 RCU_INIT_POINTER(gss_cred->gc_ctx, NULL); 1231 RCU_INIT_POINTER(gss_cred->gc_ctx, NULL);
1229 call_rcu(&cred->cr_rcu, gss_free_cred_callback); 1232 call_rcu(&cred->cr_rcu, gss_free_cred_callback);
1230 if (ctx) 1233 if (ctx)
1231 gss_put_ctx(ctx); 1234 gss_put_ctx(ctx);
1232 kref_put(&gss_auth->kref, gss_free_callback); 1235 kref_put(&gss_auth->kref, gss_free_callback);
1233 } 1236 }
1234 1237
1235 static void 1238 static void
1236 gss_destroy_cred(struct rpc_cred *cred) 1239 gss_destroy_cred(struct rpc_cred *cred)
1237 { 1240 {
1238 1241
1239 if (gss_destroying_context(cred)) 1242 if (gss_destroying_context(cred))
1240 return; 1243 return;
1241 gss_destroy_nullcred(cred); 1244 gss_destroy_nullcred(cred);
1242 } 1245 }
1243 1246
1244 /* 1247 /*
1245 * Lookup RPCSEC_GSS cred for the current process 1248 * Lookup RPCSEC_GSS cred for the current process
1246 */ 1249 */
1247 static struct rpc_cred * 1250 static struct rpc_cred *
1248 gss_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) 1251 gss_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
1249 { 1252 {
1250 return rpcauth_lookup_credcache(auth, acred, flags); 1253 return rpcauth_lookup_credcache(auth, acred, flags);
1251 } 1254 }
1252 1255
1253 static struct rpc_cred * 1256 static struct rpc_cred *
1254 gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) 1257 gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
1255 { 1258 {
1256 struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth); 1259 struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth);
1257 struct gss_cred *cred = NULL; 1260 struct gss_cred *cred = NULL;
1258 int err = -ENOMEM; 1261 int err = -ENOMEM;
1259 1262
1260 dprintk("RPC: %s for uid %d, flavor %d\n", 1263 dprintk("RPC: %s for uid %d, flavor %d\n",
1261 __func__, from_kuid(&init_user_ns, acred->uid), 1264 __func__, from_kuid(&init_user_ns, acred->uid),
1262 auth->au_flavor); 1265 auth->au_flavor);
1263 1266
1264 if (!(cred = kzalloc(sizeof(*cred), GFP_NOFS))) 1267 if (!(cred = kzalloc(sizeof(*cred), GFP_NOFS)))
1265 goto out_err; 1268 goto out_err;
1266 1269
1267 rpcauth_init_cred(&cred->gc_base, acred, auth, &gss_credops); 1270 rpcauth_init_cred(&cred->gc_base, acred, auth, &gss_credops);
1268 /* 1271 /*
1269 * Note: in order to force a call to call_refresh(), we deliberately 1272 * Note: in order to force a call to call_refresh(), we deliberately
1270 * fail to flag the credential as RPCAUTH_CRED_UPTODATE. 1273 * fail to flag the credential as RPCAUTH_CRED_UPTODATE.
1271 */ 1274 */
1272 cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW; 1275 cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW;
1273 cred->gc_service = gss_auth->service; 1276 cred->gc_service = gss_auth->service;
1274 cred->gc_principal = NULL; 1277 cred->gc_principal = NULL;
1275 if (acred->machine_cred) 1278 if (acred->machine_cred)
1276 cred->gc_principal = acred->principal; 1279 cred->gc_principal = acred->principal;
1277 kref_get(&gss_auth->kref); 1280 kref_get(&gss_auth->kref);
1278 return &cred->gc_base; 1281 return &cred->gc_base;
1279 1282
1280 out_err: 1283 out_err:
1281 dprintk("RPC: %s failed with error %d\n", __func__, err); 1284 dprintk("RPC: %s failed with error %d\n", __func__, err);
1282 return ERR_PTR(err); 1285 return ERR_PTR(err);
1283 } 1286 }
1284 1287
1285 static int 1288 static int
1286 gss_cred_init(struct rpc_auth *auth, struct rpc_cred *cred) 1289 gss_cred_init(struct rpc_auth *auth, struct rpc_cred *cred)
1287 { 1290 {
1288 struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth); 1291 struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth);
1289 struct gss_cred *gss_cred = container_of(cred,struct gss_cred, gc_base); 1292 struct gss_cred *gss_cred = container_of(cred,struct gss_cred, gc_base);
1290 int err; 1293 int err;
1291 1294
1292 do { 1295 do {
1293 err = gss_create_upcall(gss_auth, gss_cred); 1296 err = gss_create_upcall(gss_auth, gss_cred);
1294 } while (err == -EAGAIN); 1297 } while (err == -EAGAIN);
1295 return err; 1298 return err;
1296 } 1299 }
1297 1300
1301 /*
1302 * Returns -EACCES if GSS context is NULL or will expire within the
1303 * timeout (miliseconds)
1304 */
1298 static int 1305 static int
1306 gss_key_timeout(struct rpc_cred *rc)
1307 {
1308 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base);
1309 unsigned long now = jiffies;
1310 unsigned long expire;
1311
1312 if (gss_cred->gc_ctx == NULL)
1313 return -EACCES;
1314
1315 expire = gss_cred->gc_ctx->gc_expiry - (gss_key_expire_timeo * HZ);
1316
1317 if (time_after(now, expire))
1318 return -EACCES;
1319 return 0;
1320 }
1321
1322 static int
1299 gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags) 1323 gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags)
1300 { 1324 {
1301 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base); 1325 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base);
1326 int ret;
1302 1327
1303 if (test_bit(RPCAUTH_CRED_NEW, &rc->cr_flags)) 1328 if (test_bit(RPCAUTH_CRED_NEW, &rc->cr_flags))
1304 goto out; 1329 goto out;
1305 /* Don't match with creds that have expired. */ 1330 /* Don't match with creds that have expired. */
1306 if (time_after(jiffies, gss_cred->gc_ctx->gc_expiry)) 1331 if (time_after(jiffies, gss_cred->gc_ctx->gc_expiry))
1307 return 0; 1332 return 0;
1308 if (!test_bit(RPCAUTH_CRED_UPTODATE, &rc->cr_flags)) 1333 if (!test_bit(RPCAUTH_CRED_UPTODATE, &rc->cr_flags))
1309 return 0; 1334 return 0;
1310 out: 1335 out:
1311 if (acred->principal != NULL) { 1336 if (acred->principal != NULL) {
1312 if (gss_cred->gc_principal == NULL) 1337 if (gss_cred->gc_principal == NULL)
1313 return 0; 1338 return 0;
1314 return strcmp(acred->principal, gss_cred->gc_principal) == 0; 1339 ret = strcmp(acred->principal, gss_cred->gc_principal) == 0;
1340 goto check_expire;
1315 } 1341 }
1316 if (gss_cred->gc_principal != NULL) 1342 if (gss_cred->gc_principal != NULL)
1317 return 0; 1343 return 0;
1318 return uid_eq(rc->cr_uid, acred->uid); 1344 ret = uid_eq(rc->cr_uid, acred->uid);
1345
1346 check_expire:
1347 if (ret == 0)
1348 return ret;
1349
1350 /* Notify acred users of GSS context expiration timeout */
1351 if (test_bit(RPC_CRED_NOTIFY_TIMEOUT, &acred->ac_flags) &&
1352 (gss_key_timeout(rc) != 0)) {
1353 /* test will now be done from generic cred */
1354 test_and_clear_bit(RPC_CRED_NOTIFY_TIMEOUT, &acred->ac_flags);
1355 /* tell NFS layer that key will expire soon */
1356 set_bit(RPC_CRED_KEY_EXPIRE_SOON, &acred->ac_flags);
1357 }
1358 return ret;
1319 } 1359 }
1320 1360
1321 /* 1361 /*
1322 * Marshal credentials. 1362 * Marshal credentials.
1323 * Maybe we should keep a cached credential for performance reasons. 1363 * Maybe we should keep a cached credential for performance reasons.
1324 */ 1364 */
1325 static __be32 * 1365 static __be32 *
1326 gss_marshal(struct rpc_task *task, __be32 *p) 1366 gss_marshal(struct rpc_task *task, __be32 *p)
1327 { 1367 {
1328 struct rpc_rqst *req = task->tk_rqstp; 1368 struct rpc_rqst *req = task->tk_rqstp;
1329 struct rpc_cred *cred = req->rq_cred; 1369 struct rpc_cred *cred = req->rq_cred;
1330 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, 1370 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1331 gc_base); 1371 gc_base);
1332 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred); 1372 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1333 __be32 *cred_len; 1373 __be32 *cred_len;
1334 u32 maj_stat = 0; 1374 u32 maj_stat = 0;
1335 struct xdr_netobj mic; 1375 struct xdr_netobj mic;
1336 struct kvec iov; 1376 struct kvec iov;
1337 struct xdr_buf verf_buf; 1377 struct xdr_buf verf_buf;
1338 1378
1339 dprintk("RPC: %5u %s\n", task->tk_pid, __func__); 1379 dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
1340 1380
1341 *p++ = htonl(RPC_AUTH_GSS); 1381 *p++ = htonl(RPC_AUTH_GSS);
1342 cred_len = p++; 1382 cred_len = p++;
1343 1383
1344 spin_lock(&ctx->gc_seq_lock); 1384 spin_lock(&ctx->gc_seq_lock);
1345 req->rq_seqno = ctx->gc_seq++; 1385 req->rq_seqno = ctx->gc_seq++;
1346 spin_unlock(&ctx->gc_seq_lock); 1386 spin_unlock(&ctx->gc_seq_lock);
1347 1387
1348 *p++ = htonl((u32) RPC_GSS_VERSION); 1388 *p++ = htonl((u32) RPC_GSS_VERSION);
1349 *p++ = htonl((u32) ctx->gc_proc); 1389 *p++ = htonl((u32) ctx->gc_proc);
1350 *p++ = htonl((u32) req->rq_seqno); 1390 *p++ = htonl((u32) req->rq_seqno);
1351 *p++ = htonl((u32) gss_cred->gc_service); 1391 *p++ = htonl((u32) gss_cred->gc_service);
1352 p = xdr_encode_netobj(p, &ctx->gc_wire_ctx); 1392 p = xdr_encode_netobj(p, &ctx->gc_wire_ctx);
1353 *cred_len = htonl((p - (cred_len + 1)) << 2); 1393 *cred_len = htonl((p - (cred_len + 1)) << 2);
1354 1394
1355 /* We compute the checksum for the verifier over the xdr-encoded bytes 1395 /* We compute the checksum for the verifier over the xdr-encoded bytes
1356 * starting with the xid and ending at the end of the credential: */ 1396 * starting with the xid and ending at the end of the credential: */
1357 iov.iov_base = xprt_skip_transport_header(req->rq_xprt, 1397 iov.iov_base = xprt_skip_transport_header(req->rq_xprt,
1358 req->rq_snd_buf.head[0].iov_base); 1398 req->rq_snd_buf.head[0].iov_base);
1359 iov.iov_len = (u8 *)p - (u8 *)iov.iov_base; 1399 iov.iov_len = (u8 *)p - (u8 *)iov.iov_base;
1360 xdr_buf_from_iov(&iov, &verf_buf); 1400 xdr_buf_from_iov(&iov, &verf_buf);
1361 1401
1362 /* set verifier flavor*/ 1402 /* set verifier flavor*/
1363 *p++ = htonl(RPC_AUTH_GSS); 1403 *p++ = htonl(RPC_AUTH_GSS);
1364 1404
1365 mic.data = (u8 *)(p + 1); 1405 mic.data = (u8 *)(p + 1);
1366 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &verf_buf, &mic); 1406 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
1367 if (maj_stat == GSS_S_CONTEXT_EXPIRED) { 1407 if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
1368 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); 1408 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1369 } else if (maj_stat != 0) { 1409 } else if (maj_stat != 0) {
1370 printk("gss_marshal: gss_get_mic FAILED (%d)\n", maj_stat); 1410 printk("gss_marshal: gss_get_mic FAILED (%d)\n", maj_stat);
1371 goto out_put_ctx; 1411 goto out_put_ctx;
1372 } 1412 }
1373 p = xdr_encode_opaque(p, NULL, mic.len); 1413 p = xdr_encode_opaque(p, NULL, mic.len);
1374 gss_put_ctx(ctx); 1414 gss_put_ctx(ctx);
1375 return p; 1415 return p;
1376 out_put_ctx: 1416 out_put_ctx:
1377 gss_put_ctx(ctx); 1417 gss_put_ctx(ctx);
1378 return NULL; 1418 return NULL;
1379 } 1419 }
1380 1420
1381 static int gss_renew_cred(struct rpc_task *task) 1421 static int gss_renew_cred(struct rpc_task *task)
1382 { 1422 {
1383 struct rpc_cred *oldcred = task->tk_rqstp->rq_cred; 1423 struct rpc_cred *oldcred = task->tk_rqstp->rq_cred;
1384 struct gss_cred *gss_cred = container_of(oldcred, 1424 struct gss_cred *gss_cred = container_of(oldcred,
1385 struct gss_cred, 1425 struct gss_cred,
1386 gc_base); 1426 gc_base);
1387 struct rpc_auth *auth = oldcred->cr_auth; 1427 struct rpc_auth *auth = oldcred->cr_auth;
1388 struct auth_cred acred = { 1428 struct auth_cred acred = {
1389 .uid = oldcred->cr_uid, 1429 .uid = oldcred->cr_uid,
1390 .principal = gss_cred->gc_principal, 1430 .principal = gss_cred->gc_principal,
1391 .machine_cred = (gss_cred->gc_principal != NULL ? 1 : 0), 1431 .machine_cred = (gss_cred->gc_principal != NULL ? 1 : 0),
1392 }; 1432 };
1393 struct rpc_cred *new; 1433 struct rpc_cred *new;
1394 1434
1395 new = gss_lookup_cred(auth, &acred, RPCAUTH_LOOKUP_NEW); 1435 new = gss_lookup_cred(auth, &acred, RPCAUTH_LOOKUP_NEW);
1396 if (IS_ERR(new)) 1436 if (IS_ERR(new))
1397 return PTR_ERR(new); 1437 return PTR_ERR(new);
1398 task->tk_rqstp->rq_cred = new; 1438 task->tk_rqstp->rq_cred = new;
1399 put_rpccred(oldcred); 1439 put_rpccred(oldcred);
1400 return 0; 1440 return 0;
1401 } 1441 }
1402 1442
1403 static int gss_cred_is_negative_entry(struct rpc_cred *cred) 1443 static int gss_cred_is_negative_entry(struct rpc_cred *cred)
1404 { 1444 {
1405 if (test_bit(RPCAUTH_CRED_NEGATIVE, &cred->cr_flags)) { 1445 if (test_bit(RPCAUTH_CRED_NEGATIVE, &cred->cr_flags)) {
1406 unsigned long now = jiffies; 1446 unsigned long now = jiffies;
1407 unsigned long begin, expire; 1447 unsigned long begin, expire;
1408 struct gss_cred *gss_cred; 1448 struct gss_cred *gss_cred;
1409 1449
1410 gss_cred = container_of(cred, struct gss_cred, gc_base); 1450 gss_cred = container_of(cred, struct gss_cred, gc_base);
1411 begin = gss_cred->gc_upcall_timestamp; 1451 begin = gss_cred->gc_upcall_timestamp;
1412 expire = begin + gss_expired_cred_retry_delay * HZ; 1452 expire = begin + gss_expired_cred_retry_delay * HZ;
1413 1453
1414 if (time_in_range_open(now, begin, expire)) 1454 if (time_in_range_open(now, begin, expire))
1415 return 1; 1455 return 1;
1416 } 1456 }
1417 return 0; 1457 return 0;
1418 } 1458 }
1419 1459
1420 /* 1460 /*
1421 * Refresh credentials. XXX - finish 1461 * Refresh credentials. XXX - finish
1422 */ 1462 */
1423 static int 1463 static int
1424 gss_refresh(struct rpc_task *task) 1464 gss_refresh(struct rpc_task *task)
1425 { 1465 {
1426 struct rpc_cred *cred = task->tk_rqstp->rq_cred; 1466 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1427 int ret = 0; 1467 int ret = 0;
1428 1468
1429 if (gss_cred_is_negative_entry(cred)) 1469 if (gss_cred_is_negative_entry(cred))
1430 return -EKEYEXPIRED; 1470 return -EKEYEXPIRED;
1431 1471
1432 if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) && 1472 if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) &&
1433 !test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags)) { 1473 !test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags)) {
1434 ret = gss_renew_cred(task); 1474 ret = gss_renew_cred(task);
1435 if (ret < 0) 1475 if (ret < 0)
1436 goto out; 1476 goto out;
1437 cred = task->tk_rqstp->rq_cred; 1477 cred = task->tk_rqstp->rq_cred;
1438 } 1478 }
1439 1479
1440 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags)) 1480 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags))
1441 ret = gss_refresh_upcall(task); 1481 ret = gss_refresh_upcall(task);
1442 out: 1482 out:
1443 return ret; 1483 return ret;
1444 } 1484 }
1445 1485
1446 /* Dummy refresh routine: used only when destroying the context */ 1486 /* Dummy refresh routine: used only when destroying the context */
1447 static int 1487 static int
1448 gss_refresh_null(struct rpc_task *task) 1488 gss_refresh_null(struct rpc_task *task)
1449 { 1489 {
1450 return -EACCES; 1490 return -EACCES;
1451 } 1491 }
1452 1492
1453 static __be32 * 1493 static __be32 *
1454 gss_validate(struct rpc_task *task, __be32 *p) 1494 gss_validate(struct rpc_task *task, __be32 *p)
1455 { 1495 {
1456 struct rpc_cred *cred = task->tk_rqstp->rq_cred; 1496 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1457 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred); 1497 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1458 __be32 seq; 1498 __be32 seq;
1459 struct kvec iov; 1499 struct kvec iov;
1460 struct xdr_buf verf_buf; 1500 struct xdr_buf verf_buf;
1461 struct xdr_netobj mic; 1501 struct xdr_netobj mic;
1462 u32 flav,len; 1502 u32 flav,len;
1463 u32 maj_stat; 1503 u32 maj_stat;
1464 1504
1465 dprintk("RPC: %5u %s\n", task->tk_pid, __func__); 1505 dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
1466 1506
1467 flav = ntohl(*p++); 1507 flav = ntohl(*p++);
1468 if ((len = ntohl(*p++)) > RPC_MAX_AUTH_SIZE) 1508 if ((len = ntohl(*p++)) > RPC_MAX_AUTH_SIZE)
1469 goto out_bad; 1509 goto out_bad;
1470 if (flav != RPC_AUTH_GSS) 1510 if (flav != RPC_AUTH_GSS)
1471 goto out_bad; 1511 goto out_bad;
1472 seq = htonl(task->tk_rqstp->rq_seqno); 1512 seq = htonl(task->tk_rqstp->rq_seqno);
1473 iov.iov_base = &seq; 1513 iov.iov_base = &seq;
1474 iov.iov_len = sizeof(seq); 1514 iov.iov_len = sizeof(seq);
1475 xdr_buf_from_iov(&iov, &verf_buf); 1515 xdr_buf_from_iov(&iov, &verf_buf);
1476 mic.data = (u8 *)p; 1516 mic.data = (u8 *)p;
1477 mic.len = len; 1517 mic.len = len;
1478 1518
1479 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic); 1519 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
1480 if (maj_stat == GSS_S_CONTEXT_EXPIRED) 1520 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1481 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); 1521 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1482 if (maj_stat) { 1522 if (maj_stat) {
1483 dprintk("RPC: %5u %s: gss_verify_mic returned error 0x%08x\n", 1523 dprintk("RPC: %5u %s: gss_verify_mic returned error 0x%08x\n",
1484 task->tk_pid, __func__, maj_stat); 1524 task->tk_pid, __func__, maj_stat);
1485 goto out_bad; 1525 goto out_bad;
1486 } 1526 }
1487 /* We leave it to unwrap to calculate au_rslack. For now we just 1527 /* We leave it to unwrap to calculate au_rslack. For now we just
1488 * calculate the length of the verifier: */ 1528 * calculate the length of the verifier: */
1489 cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2; 1529 cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2;
1490 gss_put_ctx(ctx); 1530 gss_put_ctx(ctx);
1491 dprintk("RPC: %5u %s: gss_verify_mic succeeded.\n", 1531 dprintk("RPC: %5u %s: gss_verify_mic succeeded.\n",
1492 task->tk_pid, __func__); 1532 task->tk_pid, __func__);
1493 return p + XDR_QUADLEN(len); 1533 return p + XDR_QUADLEN(len);
1494 out_bad: 1534 out_bad:
1495 gss_put_ctx(ctx); 1535 gss_put_ctx(ctx);
1496 dprintk("RPC: %5u %s failed.\n", task->tk_pid, __func__); 1536 dprintk("RPC: %5u %s failed.\n", task->tk_pid, __func__);
1497 return NULL; 1537 return NULL;
1498 } 1538 }
1499 1539
1500 static void gss_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp, 1540 static void gss_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp,
1501 __be32 *p, void *obj) 1541 __be32 *p, void *obj)
1502 { 1542 {
1503 struct xdr_stream xdr; 1543 struct xdr_stream xdr;
1504 1544
1505 xdr_init_encode(&xdr, &rqstp->rq_snd_buf, p); 1545 xdr_init_encode(&xdr, &rqstp->rq_snd_buf, p);
1506 encode(rqstp, &xdr, obj); 1546 encode(rqstp, &xdr, obj);
1507 } 1547 }
1508 1548
1509 static inline int 1549 static inline int
1510 gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, 1550 gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1511 kxdreproc_t encode, struct rpc_rqst *rqstp, 1551 kxdreproc_t encode, struct rpc_rqst *rqstp,
1512 __be32 *p, void *obj) 1552 __be32 *p, void *obj)
1513 { 1553 {
1514 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; 1554 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
1515 struct xdr_buf integ_buf; 1555 struct xdr_buf integ_buf;
1516 __be32 *integ_len = NULL; 1556 __be32 *integ_len = NULL;
1517 struct xdr_netobj mic; 1557 struct xdr_netobj mic;
1518 u32 offset; 1558 u32 offset;
1519 __be32 *q; 1559 __be32 *q;
1520 struct kvec *iov; 1560 struct kvec *iov;
1521 u32 maj_stat = 0; 1561 u32 maj_stat = 0;
1522 int status = -EIO; 1562 int status = -EIO;
1523 1563
1524 integ_len = p++; 1564 integ_len = p++;
1525 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; 1565 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
1526 *p++ = htonl(rqstp->rq_seqno); 1566 *p++ = htonl(rqstp->rq_seqno);
1527 1567
1528 gss_wrap_req_encode(encode, rqstp, p, obj); 1568 gss_wrap_req_encode(encode, rqstp, p, obj);
1529 1569
1530 if (xdr_buf_subsegment(snd_buf, &integ_buf, 1570 if (xdr_buf_subsegment(snd_buf, &integ_buf,
1531 offset, snd_buf->len - offset)) 1571 offset, snd_buf->len - offset))
1532 return status; 1572 return status;
1533 *integ_len = htonl(integ_buf.len); 1573 *integ_len = htonl(integ_buf.len);
1534 1574
1535 /* guess whether we're in the head or the tail: */ 1575 /* guess whether we're in the head or the tail: */
1536 if (snd_buf->page_len || snd_buf->tail[0].iov_len) 1576 if (snd_buf->page_len || snd_buf->tail[0].iov_len)
1537 iov = snd_buf->tail; 1577 iov = snd_buf->tail;
1538 else 1578 else
1539 iov = snd_buf->head; 1579 iov = snd_buf->head;
1540 p = iov->iov_base + iov->iov_len; 1580 p = iov->iov_base + iov->iov_len;
1541 mic.data = (u8 *)(p + 1); 1581 mic.data = (u8 *)(p + 1);
1542 1582
1543 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &integ_buf, &mic); 1583 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
1544 status = -EIO; /* XXX? */ 1584 status = -EIO; /* XXX? */
1545 if (maj_stat == GSS_S_CONTEXT_EXPIRED) 1585 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1546 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); 1586 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1547 else if (maj_stat) 1587 else if (maj_stat)
1548 return status; 1588 return status;
1549 q = xdr_encode_opaque(p, NULL, mic.len); 1589 q = xdr_encode_opaque(p, NULL, mic.len);
1550 1590
1551 offset = (u8 *)q - (u8 *)p; 1591 offset = (u8 *)q - (u8 *)p;
1552 iov->iov_len += offset; 1592 iov->iov_len += offset;
1553 snd_buf->len += offset; 1593 snd_buf->len += offset;
1554 return 0; 1594 return 0;
1555 } 1595 }
1556 1596
1557 static void 1597 static void
1558 priv_release_snd_buf(struct rpc_rqst *rqstp) 1598 priv_release_snd_buf(struct rpc_rqst *rqstp)
1559 { 1599 {
1560 int i; 1600 int i;
1561 1601
1562 for (i=0; i < rqstp->rq_enc_pages_num; i++) 1602 for (i=0; i < rqstp->rq_enc_pages_num; i++)
1563 __free_page(rqstp->rq_enc_pages[i]); 1603 __free_page(rqstp->rq_enc_pages[i]);
1564 kfree(rqstp->rq_enc_pages); 1604 kfree(rqstp->rq_enc_pages);
1565 } 1605 }
1566 1606
1567 static int 1607 static int
1568 alloc_enc_pages(struct rpc_rqst *rqstp) 1608 alloc_enc_pages(struct rpc_rqst *rqstp)
1569 { 1609 {
1570 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; 1610 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
1571 int first, last, i; 1611 int first, last, i;
1572 1612
1573 if (snd_buf->page_len == 0) { 1613 if (snd_buf->page_len == 0) {
1574 rqstp->rq_enc_pages_num = 0; 1614 rqstp->rq_enc_pages_num = 0;
1575 return 0; 1615 return 0;
1576 } 1616 }
1577 1617
1578 first = snd_buf->page_base >> PAGE_CACHE_SHIFT; 1618 first = snd_buf->page_base >> PAGE_CACHE_SHIFT;
1579 last = (snd_buf->page_base + snd_buf->page_len - 1) >> PAGE_CACHE_SHIFT; 1619 last = (snd_buf->page_base + snd_buf->page_len - 1) >> PAGE_CACHE_SHIFT;
1580 rqstp->rq_enc_pages_num = last - first + 1 + 1; 1620 rqstp->rq_enc_pages_num = last - first + 1 + 1;
1581 rqstp->rq_enc_pages 1621 rqstp->rq_enc_pages
1582 = kmalloc(rqstp->rq_enc_pages_num * sizeof(struct page *), 1622 = kmalloc(rqstp->rq_enc_pages_num * sizeof(struct page *),
1583 GFP_NOFS); 1623 GFP_NOFS);
1584 if (!rqstp->rq_enc_pages) 1624 if (!rqstp->rq_enc_pages)
1585 goto out; 1625 goto out;
1586 for (i=0; i < rqstp->rq_enc_pages_num; i++) { 1626 for (i=0; i < rqstp->rq_enc_pages_num; i++) {
1587 rqstp->rq_enc_pages[i] = alloc_page(GFP_NOFS); 1627 rqstp->rq_enc_pages[i] = alloc_page(GFP_NOFS);
1588 if (rqstp->rq_enc_pages[i] == NULL) 1628 if (rqstp->rq_enc_pages[i] == NULL)
1589 goto out_free; 1629 goto out_free;
1590 } 1630 }
1591 rqstp->rq_release_snd_buf = priv_release_snd_buf; 1631 rqstp->rq_release_snd_buf = priv_release_snd_buf;
1592 return 0; 1632 return 0;
1593 out_free: 1633 out_free:
1594 rqstp->rq_enc_pages_num = i; 1634 rqstp->rq_enc_pages_num = i;
1595 priv_release_snd_buf(rqstp); 1635 priv_release_snd_buf(rqstp);
1596 out: 1636 out:
1597 return -EAGAIN; 1637 return -EAGAIN;
1598 } 1638 }
1599 1639
1600 static inline int 1640 static inline int
1601 gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, 1641 gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1602 kxdreproc_t encode, struct rpc_rqst *rqstp, 1642 kxdreproc_t encode, struct rpc_rqst *rqstp,
1603 __be32 *p, void *obj) 1643 __be32 *p, void *obj)
1604 { 1644 {
1605 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; 1645 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
1606 u32 offset; 1646 u32 offset;
1607 u32 maj_stat; 1647 u32 maj_stat;
1608 int status; 1648 int status;
1609 __be32 *opaque_len; 1649 __be32 *opaque_len;
1610 struct page **inpages; 1650 struct page **inpages;
1611 int first; 1651 int first;
1612 int pad; 1652 int pad;
1613 struct kvec *iov; 1653 struct kvec *iov;
1614 char *tmp; 1654 char *tmp;
1615 1655
1616 opaque_len = p++; 1656 opaque_len = p++;
1617 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; 1657 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
1618 *p++ = htonl(rqstp->rq_seqno); 1658 *p++ = htonl(rqstp->rq_seqno);
1619 1659
1620 gss_wrap_req_encode(encode, rqstp, p, obj); 1660 gss_wrap_req_encode(encode, rqstp, p, obj);
1621 1661
1622 status = alloc_enc_pages(rqstp); 1662 status = alloc_enc_pages(rqstp);
1623 if (status) 1663 if (status)
1624 return status; 1664 return status;
1625 first = snd_buf->page_base >> PAGE_CACHE_SHIFT; 1665 first = snd_buf->page_base >> PAGE_CACHE_SHIFT;
1626 inpages = snd_buf->pages + first; 1666 inpages = snd_buf->pages + first;
1627 snd_buf->pages = rqstp->rq_enc_pages; 1667 snd_buf->pages = rqstp->rq_enc_pages;
1628 snd_buf->page_base -= first << PAGE_CACHE_SHIFT; 1668 snd_buf->page_base -= first << PAGE_CACHE_SHIFT;
1629 /* 1669 /*
1630 * Give the tail its own page, in case we need extra space in the 1670 * Give the tail its own page, in case we need extra space in the
1631 * head when wrapping: 1671 * head when wrapping:
1632 * 1672 *
1633 * call_allocate() allocates twice the slack space required 1673 * call_allocate() allocates twice the slack space required
1634 * by the authentication flavor to rq_callsize. 1674 * by the authentication flavor to rq_callsize.
1635 * For GSS, slack is GSS_CRED_SLACK. 1675 * For GSS, slack is GSS_CRED_SLACK.
1636 */ 1676 */
1637 if (snd_buf->page_len || snd_buf->tail[0].iov_len) { 1677 if (snd_buf->page_len || snd_buf->tail[0].iov_len) {
1638 tmp = page_address(rqstp->rq_enc_pages[rqstp->rq_enc_pages_num - 1]); 1678 tmp = page_address(rqstp->rq_enc_pages[rqstp->rq_enc_pages_num - 1]);
1639 memcpy(tmp, snd_buf->tail[0].iov_base, snd_buf->tail[0].iov_len); 1679 memcpy(tmp, snd_buf->tail[0].iov_base, snd_buf->tail[0].iov_len);
1640 snd_buf->tail[0].iov_base = tmp; 1680 snd_buf->tail[0].iov_base = tmp;
1641 } 1681 }
1642 maj_stat = gss_wrap(ctx->gc_gss_ctx, offset, snd_buf, inpages); 1682 maj_stat = gss_wrap(ctx->gc_gss_ctx, offset, snd_buf, inpages);
1643 /* slack space should prevent this ever happening: */ 1683 /* slack space should prevent this ever happening: */
1644 BUG_ON(snd_buf->len > snd_buf->buflen); 1684 BUG_ON(snd_buf->len > snd_buf->buflen);
1645 status = -EIO; 1685 status = -EIO;
1646 /* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was 1686 /* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was
1647 * done anyway, so it's safe to put the request on the wire: */ 1687 * done anyway, so it's safe to put the request on the wire: */
1648 if (maj_stat == GSS_S_CONTEXT_EXPIRED) 1688 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1649 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); 1689 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1650 else if (maj_stat) 1690 else if (maj_stat)
1651 return status; 1691 return status;
1652 1692
1653 *opaque_len = htonl(snd_buf->len - offset); 1693 *opaque_len = htonl(snd_buf->len - offset);
1654 /* guess whether we're in the head or the tail: */ 1694 /* guess whether we're in the head or the tail: */
1655 if (snd_buf->page_len || snd_buf->tail[0].iov_len) 1695 if (snd_buf->page_len || snd_buf->tail[0].iov_len)
1656 iov = snd_buf->tail; 1696 iov = snd_buf->tail;
1657 else 1697 else
1658 iov = snd_buf->head; 1698 iov = snd_buf->head;
1659 p = iov->iov_base + iov->iov_len; 1699 p = iov->iov_base + iov->iov_len;
1660 pad = 3 - ((snd_buf->len - offset - 1) & 3); 1700 pad = 3 - ((snd_buf->len - offset - 1) & 3);
1661 memset(p, 0, pad); 1701 memset(p, 0, pad);
1662 iov->iov_len += pad; 1702 iov->iov_len += pad;
1663 snd_buf->len += pad; 1703 snd_buf->len += pad;
1664 1704
1665 return 0; 1705 return 0;
1666 } 1706 }
1667 1707
1668 static int 1708 static int
1669 gss_wrap_req(struct rpc_task *task, 1709 gss_wrap_req(struct rpc_task *task,
1670 kxdreproc_t encode, void *rqstp, __be32 *p, void *obj) 1710 kxdreproc_t encode, void *rqstp, __be32 *p, void *obj)
1671 { 1711 {
1672 struct rpc_cred *cred = task->tk_rqstp->rq_cred; 1712 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1673 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, 1713 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1674 gc_base); 1714 gc_base);
1675 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred); 1715 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1676 int status = -EIO; 1716 int status = -EIO;
1677 1717
1678 dprintk("RPC: %5u %s\n", task->tk_pid, __func__); 1718 dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
1679 if (ctx->gc_proc != RPC_GSS_PROC_DATA) { 1719 if (ctx->gc_proc != RPC_GSS_PROC_DATA) {
1680 /* The spec seems a little ambiguous here, but I think that not 1720 /* The spec seems a little ambiguous here, but I think that not
1681 * wrapping context destruction requests makes the most sense. 1721 * wrapping context destruction requests makes the most sense.
1682 */ 1722 */
1683 gss_wrap_req_encode(encode, rqstp, p, obj); 1723 gss_wrap_req_encode(encode, rqstp, p, obj);
1684 status = 0; 1724 status = 0;
1685 goto out; 1725 goto out;
1686 } 1726 }
1687 switch (gss_cred->gc_service) { 1727 switch (gss_cred->gc_service) {
1688 case RPC_GSS_SVC_NONE: 1728 case RPC_GSS_SVC_NONE:
1689 gss_wrap_req_encode(encode, rqstp, p, obj); 1729 gss_wrap_req_encode(encode, rqstp, p, obj);
1690 status = 0; 1730 status = 0;
1691 break; 1731 break;
1692 case RPC_GSS_SVC_INTEGRITY: 1732 case RPC_GSS_SVC_INTEGRITY:
1693 status = gss_wrap_req_integ(cred, ctx, encode, rqstp, p, obj); 1733 status = gss_wrap_req_integ(cred, ctx, encode, rqstp, p, obj);
1694 break; 1734 break;
1695 case RPC_GSS_SVC_PRIVACY: 1735 case RPC_GSS_SVC_PRIVACY:
1696 status = gss_wrap_req_priv(cred, ctx, encode, rqstp, p, obj); 1736 status = gss_wrap_req_priv(cred, ctx, encode, rqstp, p, obj);
1697 break; 1737 break;
1698 } 1738 }
1699 out: 1739 out:
1700 gss_put_ctx(ctx); 1740 gss_put_ctx(ctx);
1701 dprintk("RPC: %5u %s returning %d\n", task->tk_pid, __func__, status); 1741 dprintk("RPC: %5u %s returning %d\n", task->tk_pid, __func__, status);
1702 return status; 1742 return status;
1703 } 1743 }
1704 1744
1705 static inline int 1745 static inline int
1706 gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, 1746 gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1707 struct rpc_rqst *rqstp, __be32 **p) 1747 struct rpc_rqst *rqstp, __be32 **p)
1708 { 1748 {
1709 struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf; 1749 struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
1710 struct xdr_buf integ_buf; 1750 struct xdr_buf integ_buf;
1711 struct xdr_netobj mic; 1751 struct xdr_netobj mic;
1712 u32 data_offset, mic_offset; 1752 u32 data_offset, mic_offset;
1713 u32 integ_len; 1753 u32 integ_len;
1714 u32 maj_stat; 1754 u32 maj_stat;
1715 int status = -EIO; 1755 int status = -EIO;
1716 1756
1717 integ_len = ntohl(*(*p)++); 1757 integ_len = ntohl(*(*p)++);
1718 if (integ_len & 3) 1758 if (integ_len & 3)
1719 return status; 1759 return status;
1720 data_offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base; 1760 data_offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base;
1721 mic_offset = integ_len + data_offset; 1761 mic_offset = integ_len + data_offset;
1722 if (mic_offset > rcv_buf->len) 1762 if (mic_offset > rcv_buf->len)
1723 return status; 1763 return status;
1724 if (ntohl(*(*p)++) != rqstp->rq_seqno) 1764 if (ntohl(*(*p)++) != rqstp->rq_seqno)
1725 return status; 1765 return status;
1726 1766
1727 if (xdr_buf_subsegment(rcv_buf, &integ_buf, data_offset, 1767 if (xdr_buf_subsegment(rcv_buf, &integ_buf, data_offset,
1728 mic_offset - data_offset)) 1768 mic_offset - data_offset))
1729 return status; 1769 return status;
1730 1770
1731 if (xdr_buf_read_netobj(rcv_buf, &mic, mic_offset)) 1771 if (xdr_buf_read_netobj(rcv_buf, &mic, mic_offset))
1732 return status; 1772 return status;
1733 1773
1734 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf, &mic); 1774 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
1735 if (maj_stat == GSS_S_CONTEXT_EXPIRED) 1775 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1736 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); 1776 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1737 if (maj_stat != GSS_S_COMPLETE) 1777 if (maj_stat != GSS_S_COMPLETE)
1738 return status; 1778 return status;
1739 return 0; 1779 return 0;
1740 } 1780 }
1741 1781
1742 static inline int 1782 static inline int
1743 gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, 1783 gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
1744 struct rpc_rqst *rqstp, __be32 **p) 1784 struct rpc_rqst *rqstp, __be32 **p)
1745 { 1785 {
1746 struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf; 1786 struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
1747 u32 offset; 1787 u32 offset;
1748 u32 opaque_len; 1788 u32 opaque_len;
1749 u32 maj_stat; 1789 u32 maj_stat;
1750 int status = -EIO; 1790 int status = -EIO;
1751 1791
1752 opaque_len = ntohl(*(*p)++); 1792 opaque_len = ntohl(*(*p)++);
1753 offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base; 1793 offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base;
1754 if (offset + opaque_len > rcv_buf->len) 1794 if (offset + opaque_len > rcv_buf->len)
1755 return status; 1795 return status;
1756 /* remove padding: */ 1796 /* remove padding: */
1757 rcv_buf->len = offset + opaque_len; 1797 rcv_buf->len = offset + opaque_len;
1758 1798
1759 maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf); 1799 maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf);
1760 if (maj_stat == GSS_S_CONTEXT_EXPIRED) 1800 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
1761 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags); 1801 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1762 if (maj_stat != GSS_S_COMPLETE) 1802 if (maj_stat != GSS_S_COMPLETE)
1763 return status; 1803 return status;
1764 if (ntohl(*(*p)++) != rqstp->rq_seqno) 1804 if (ntohl(*(*p)++) != rqstp->rq_seqno)
1765 return status; 1805 return status;
1766 1806
1767 return 0; 1807 return 0;
1768 } 1808 }
1769 1809
1770 static int 1810 static int
1771 gss_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp, 1811 gss_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp,
1772 __be32 *p, void *obj) 1812 __be32 *p, void *obj)
1773 { 1813 {
1774 struct xdr_stream xdr; 1814 struct xdr_stream xdr;
1775 1815
1776 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); 1816 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
1777 return decode(rqstp, &xdr, obj); 1817 return decode(rqstp, &xdr, obj);
1778 } 1818 }
1779 1819
1780 static int 1820 static int
1781 gss_unwrap_resp(struct rpc_task *task, 1821 gss_unwrap_resp(struct rpc_task *task,
1782 kxdrdproc_t decode, void *rqstp, __be32 *p, void *obj) 1822 kxdrdproc_t decode, void *rqstp, __be32 *p, void *obj)
1783 { 1823 {
1784 struct rpc_cred *cred = task->tk_rqstp->rq_cred; 1824 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1785 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, 1825 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1786 gc_base); 1826 gc_base);
1787 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred); 1827 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1788 __be32 *savedp = p; 1828 __be32 *savedp = p;
1789 struct kvec *head = ((struct rpc_rqst *)rqstp)->rq_rcv_buf.head; 1829 struct kvec *head = ((struct rpc_rqst *)rqstp)->rq_rcv_buf.head;
1790 int savedlen = head->iov_len; 1830 int savedlen = head->iov_len;
1791 int status = -EIO; 1831 int status = -EIO;
1792 1832
1793 if (ctx->gc_proc != RPC_GSS_PROC_DATA) 1833 if (ctx->gc_proc != RPC_GSS_PROC_DATA)
1794 goto out_decode; 1834 goto out_decode;
1795 switch (gss_cred->gc_service) { 1835 switch (gss_cred->gc_service) {
1796 case RPC_GSS_SVC_NONE: 1836 case RPC_GSS_SVC_NONE:
1797 break; 1837 break;
1798 case RPC_GSS_SVC_INTEGRITY: 1838 case RPC_GSS_SVC_INTEGRITY:
1799 status = gss_unwrap_resp_integ(cred, ctx, rqstp, &p); 1839 status = gss_unwrap_resp_integ(cred, ctx, rqstp, &p);
1800 if (status) 1840 if (status)
1801 goto out; 1841 goto out;
1802 break; 1842 break;
1803 case RPC_GSS_SVC_PRIVACY: 1843 case RPC_GSS_SVC_PRIVACY:
1804 status = gss_unwrap_resp_priv(cred, ctx, rqstp, &p); 1844 status = gss_unwrap_resp_priv(cred, ctx, rqstp, &p);
1805 if (status) 1845 if (status)
1806 goto out; 1846 goto out;
1807 break; 1847 break;
1808 } 1848 }
1809 /* take into account extra slack for integrity and privacy cases: */ 1849 /* take into account extra slack for integrity and privacy cases: */
1810 cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp) 1850 cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp)
1811 + (savedlen - head->iov_len); 1851 + (savedlen - head->iov_len);
1812 out_decode: 1852 out_decode:
1813 status = gss_unwrap_req_decode(decode, rqstp, p, obj); 1853 status = gss_unwrap_req_decode(decode, rqstp, p, obj);
1814 out: 1854 out:
1815 gss_put_ctx(ctx); 1855 gss_put_ctx(ctx);
1816 dprintk("RPC: %5u %s returning %d\n", 1856 dprintk("RPC: %5u %s returning %d\n",
1817 task->tk_pid, __func__, status); 1857 task->tk_pid, __func__, status);
1818 return status; 1858 return status;
1819 } 1859 }
1820 1860
1821 static const struct rpc_authops authgss_ops = { 1861 static const struct rpc_authops authgss_ops = {
1822 .owner = THIS_MODULE, 1862 .owner = THIS_MODULE,
1823 .au_flavor = RPC_AUTH_GSS, 1863 .au_flavor = RPC_AUTH_GSS,
1824 .au_name = "RPCSEC_GSS", 1864 .au_name = "RPCSEC_GSS",
1825 .create = gss_create, 1865 .create = gss_create,
1826 .destroy = gss_destroy, 1866 .destroy = gss_destroy,
1827 .lookup_cred = gss_lookup_cred, 1867 .lookup_cred = gss_lookup_cred,
1828 .crcreate = gss_create_cred, 1868 .crcreate = gss_create_cred,
1829 .list_pseudoflavors = gss_mech_list_pseudoflavors, 1869 .list_pseudoflavors = gss_mech_list_pseudoflavors,
1830 .info2flavor = gss_mech_info2flavor, 1870 .info2flavor = gss_mech_info2flavor,
1831 .flavor2info = gss_mech_flavor2info, 1871 .flavor2info = gss_mech_flavor2info,
1832 }; 1872 };
1833 1873
1834 static const struct rpc_credops gss_credops = { 1874 static const struct rpc_credops gss_credops = {
1835 .cr_name = "AUTH_GSS", 1875 .cr_name = "AUTH_GSS",
1836 .crdestroy = gss_destroy_cred, 1876 .crdestroy = gss_destroy_cred,
1837 .cr_init = gss_cred_init, 1877 .cr_init = gss_cred_init,
1838 .crbind = rpcauth_generic_bind_cred, 1878 .crbind = rpcauth_generic_bind_cred,
1839 .crmatch = gss_match, 1879 .crmatch = gss_match,
1840 .crmarshal = gss_marshal, 1880 .crmarshal = gss_marshal,
1841 .crrefresh = gss_refresh, 1881 .crrefresh = gss_refresh,
1842 .crvalidate = gss_validate, 1882 .crvalidate = gss_validate,
1843 .crwrap_req = gss_wrap_req, 1883 .crwrap_req = gss_wrap_req,
1844 .crunwrap_resp = gss_unwrap_resp, 1884 .crunwrap_resp = gss_unwrap_resp,
1885 .crkey_timeout = gss_key_timeout,
1845 }; 1886 };
1846 1887
1847 static const struct rpc_credops gss_nullops = { 1888 static const struct rpc_credops gss_nullops = {
1848 .cr_name = "AUTH_GSS", 1889 .cr_name = "AUTH_GSS",
1849 .crdestroy = gss_destroy_nullcred, 1890 .crdestroy = gss_destroy_nullcred,
1850 .crbind = rpcauth_generic_bind_cred, 1891 .crbind = rpcauth_generic_bind_cred,
1851 .crmatch = gss_match, 1892 .crmatch = gss_match,
1852 .crmarshal = gss_marshal, 1893 .crmarshal = gss_marshal,
1853 .crrefresh = gss_refresh_null, 1894 .crrefresh = gss_refresh_null,
1854 .crvalidate = gss_validate, 1895 .crvalidate = gss_validate,
1855 .crwrap_req = gss_wrap_req, 1896 .crwrap_req = gss_wrap_req,
1856 .crunwrap_resp = gss_unwrap_resp, 1897 .crunwrap_resp = gss_unwrap_resp,
1857 }; 1898 };
1858 1899
1859 static const struct rpc_pipe_ops gss_upcall_ops_v0 = { 1900 static const struct rpc_pipe_ops gss_upcall_ops_v0 = {
1860 .upcall = rpc_pipe_generic_upcall, 1901 .upcall = rpc_pipe_generic_upcall,
1861 .downcall = gss_pipe_downcall, 1902 .downcall = gss_pipe_downcall,
1862 .destroy_msg = gss_pipe_destroy_msg, 1903 .destroy_msg = gss_pipe_destroy_msg,
1863 .open_pipe = gss_pipe_open_v0, 1904 .open_pipe = gss_pipe_open_v0,
1864 .release_pipe = gss_pipe_release, 1905 .release_pipe = gss_pipe_release,
1865 }; 1906 };
1866 1907
1867 static const struct rpc_pipe_ops gss_upcall_ops_v1 = { 1908 static const struct rpc_pipe_ops gss_upcall_ops_v1 = {
1868 .upcall = rpc_pipe_generic_upcall, 1909 .upcall = rpc_pipe_generic_upcall,
1869 .downcall = gss_pipe_downcall, 1910 .downcall = gss_pipe_downcall,
1870 .destroy_msg = gss_pipe_destroy_msg, 1911 .destroy_msg = gss_pipe_destroy_msg,
1871 .open_pipe = gss_pipe_open_v1, 1912 .open_pipe = gss_pipe_open_v1,
1872 .release_pipe = gss_pipe_release, 1913 .release_pipe = gss_pipe_release,
1873 }; 1914 };
1874 1915
1875 static __net_init int rpcsec_gss_init_net(struct net *net) 1916 static __net_init int rpcsec_gss_init_net(struct net *net)
1876 { 1917 {
1877 return gss_svc_init_net(net); 1918 return gss_svc_init_net(net);
1878 } 1919 }
1879 1920
1880 static __net_exit void rpcsec_gss_exit_net(struct net *net) 1921 static __net_exit void rpcsec_gss_exit_net(struct net *net)
1881 { 1922 {
1882 gss_svc_shutdown_net(net); 1923 gss_svc_shutdown_net(net);
1883 } 1924 }
1884 1925
1885 static struct pernet_operations rpcsec_gss_net_ops = { 1926 static struct pernet_operations rpcsec_gss_net_ops = {
1886 .init = rpcsec_gss_init_net, 1927 .init = rpcsec_gss_init_net,
1887 .exit = rpcsec_gss_exit_net, 1928 .exit = rpcsec_gss_exit_net,
1888 }; 1929 };
1889 1930
1890 /* 1931 /*
1891 * Initialize RPCSEC_GSS module 1932 * Initialize RPCSEC_GSS module
1892 */ 1933 */
1893 static int __init init_rpcsec_gss(void) 1934 static int __init init_rpcsec_gss(void)
1894 { 1935 {
1895 int err = 0; 1936 int err = 0;
1896 1937
1897 err = rpcauth_register(&authgss_ops); 1938 err = rpcauth_register(&authgss_ops);
1898 if (err) 1939 if (err)
1899 goto out; 1940 goto out;
1900 err = gss_svc_init(); 1941 err = gss_svc_init();
1901 if (err) 1942 if (err)
1902 goto out_unregister; 1943 goto out_unregister;
1903 err = register_pernet_subsys(&rpcsec_gss_net_ops); 1944 err = register_pernet_subsys(&rpcsec_gss_net_ops);
1904 if (err) 1945 if (err)
1905 goto out_svc_exit; 1946 goto out_svc_exit;
1906 rpc_init_wait_queue(&pipe_version_rpc_waitqueue, "gss pipe version"); 1947 rpc_init_wait_queue(&pipe_version_rpc_waitqueue, "gss pipe version");
1907 return 0; 1948 return 0;
1908 out_svc_exit: 1949 out_svc_exit:
1909 gss_svc_shutdown(); 1950 gss_svc_shutdown();
1910 out_unregister: 1951 out_unregister:
1911 rpcauth_unregister(&authgss_ops); 1952 rpcauth_unregister(&authgss_ops);
1912 out: 1953 out:
1913 return err; 1954 return err;
1914 } 1955 }
1915 1956
1916 static void __exit exit_rpcsec_gss(void) 1957 static void __exit exit_rpcsec_gss(void)
1917 { 1958 {
1918 unregister_pernet_subsys(&rpcsec_gss_net_ops); 1959 unregister_pernet_subsys(&rpcsec_gss_net_ops);
1919 gss_svc_shutdown(); 1960 gss_svc_shutdown();
1920 rpcauth_unregister(&authgss_ops); 1961 rpcauth_unregister(&authgss_ops);
1921 rcu_barrier(); /* Wait for completion of call_rcu()'s */ 1962 rcu_barrier(); /* Wait for completion of call_rcu()'s */
1922 } 1963 }
1923 1964
1924 MODULE_ALIAS("rpc-auth-6"); 1965 MODULE_ALIAS("rpc-auth-6");
1925 MODULE_LICENSE("GPL"); 1966 MODULE_LICENSE("GPL");
1926 module_param_named(expired_cred_retry_delay, 1967 module_param_named(expired_cred_retry_delay,
1927 gss_expired_cred_retry_delay, 1968 gss_expired_cred_retry_delay,
1928 uint, 0644); 1969 uint, 0644);
1929 MODULE_PARM_DESC(expired_cred_retry_delay, "Timeout (in seconds) until " 1970 MODULE_PARM_DESC(expired_cred_retry_delay, "Timeout (in seconds) until "
1930 "the RPC engine retries an expired credential"); 1971 "the RPC engine retries an expired credential");
1972
1973 module_param_named(key_expire_timeo,
1974 gss_key_expire_timeo,
1975 uint, 0644);
1976 MODULE_PARM_DESC(key_expire_timeo, "Time (in seconds) at the end of a "
1977 "credential keys lifetime where the NFS layer cleans up "
1978 "prior to key expiration");
1931 1979
1932 module_init(init_rpcsec_gss) 1980 module_init(init_rpcsec_gss)
1933 module_exit(exit_rpcsec_gss) 1981 module_exit(exit_rpcsec_gss)
1934 1982