diff options
-rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 66 |
1 files changed, 59 insertions, 7 deletions
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index aadb4e8d6aa7..237d935747a5 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -78,7 +78,8 @@ struct rsi { | |||
78 | 78 | ||
79 | static struct cache_head *rsi_table[RSI_HASHMAX]; | 79 | static struct cache_head *rsi_table[RSI_HASHMAX]; |
80 | static struct cache_detail rsi_cache; | 80 | static struct cache_detail rsi_cache; |
81 | static struct rsi *rsi_lookup(struct rsi *item, int set); | 81 | static struct rsi *rsi_update(struct rsi *new, struct rsi *old); |
82 | static struct rsi *rsi_lookup(struct rsi *item); | ||
82 | 83 | ||
83 | static void rsi_free(struct rsi *rsii) | 84 | static void rsi_free(struct rsi *rsii) |
84 | { | 85 | { |
@@ -103,8 +104,10 @@ static inline int rsi_hash(struct rsi *item) | |||
103 | ^ hash_mem(item->in_token.data, item->in_token.len, RSI_HASHBITS); | 104 | ^ hash_mem(item->in_token.data, item->in_token.len, RSI_HASHBITS); |
104 | } | 105 | } |
105 | 106 | ||
106 | static inline int rsi_match(struct rsi *item, struct rsi *tmp) | 107 | static int rsi_match(struct cache_head *a, struct cache_head *b) |
107 | { | 108 | { |
109 | struct rsi *item = container_of(a, struct rsi, h); | ||
110 | struct rsi *tmp = container_of(b, struct rsi, h); | ||
108 | return netobj_equal(&item->in_handle, &tmp->in_handle) | 111 | return netobj_equal(&item->in_handle, &tmp->in_handle) |
109 | && netobj_equal(&item->in_token, &tmp->in_token); | 112 | && netobj_equal(&item->in_token, &tmp->in_token); |
110 | } | 113 | } |
@@ -125,8 +128,11 @@ static inline int dup_netobj(struct xdr_netobj *dst, struct xdr_netobj *src) | |||
125 | return dup_to_netobj(dst, src->data, src->len); | 128 | return dup_to_netobj(dst, src->data, src->len); |
126 | } | 129 | } |
127 | 130 | ||
128 | static inline void rsi_init(struct rsi *new, struct rsi *item) | 131 | static void rsi_init(struct cache_head *cnew, struct cache_head *citem) |
129 | { | 132 | { |
133 | struct rsi *new = container_of(cnew, struct rsi, h); | ||
134 | struct rsi *item = container_of(citem, struct rsi, h); | ||
135 | |||
130 | new->out_handle.data = NULL; | 136 | new->out_handle.data = NULL; |
131 | new->out_handle.len = 0; | 137 | new->out_handle.len = 0; |
132 | new->out_token.data = NULL; | 138 | new->out_token.data = NULL; |
@@ -141,8 +147,11 @@ static inline void rsi_init(struct rsi *new, struct rsi *item) | |||
141 | item->in_token.data = NULL; | 147 | item->in_token.data = NULL; |
142 | } | 148 | } |
143 | 149 | ||
144 | static inline void rsi_update(struct rsi *new, struct rsi *item) | 150 | static void update_rsi(struct cache_head *cnew, struct cache_head *citem) |
145 | { | 151 | { |
152 | struct rsi *new = container_of(cnew, struct rsi, h); | ||
153 | struct rsi *item = container_of(citem, struct rsi, h); | ||
154 | |||
146 | BUG_ON(new->out_handle.data || new->out_token.data); | 155 | BUG_ON(new->out_handle.data || new->out_token.data); |
147 | new->out_handle.len = item->out_handle.len; | 156 | new->out_handle.len = item->out_handle.len; |
148 | item->out_handle.len = 0; | 157 | item->out_handle.len = 0; |
@@ -157,6 +166,15 @@ static inline void rsi_update(struct rsi *new, struct rsi *item) | |||
157 | new->minor_status = item->minor_status; | 166 | new->minor_status = item->minor_status; |
158 | } | 167 | } |
159 | 168 | ||
169 | static struct cache_head *rsi_alloc(void) | ||
170 | { | ||
171 | struct rsi *rsii = kmalloc(sizeof(*rsii), GFP_KERNEL); | ||
172 | if (rsii) | ||
173 | return &rsii->h; | ||
174 | else | ||
175 | return NULL; | ||
176 | } | ||
177 | |||
160 | static void rsi_request(struct cache_detail *cd, | 178 | static void rsi_request(struct cache_detail *cd, |
161 | struct cache_head *h, | 179 | struct cache_head *h, |
162 | char **bpp, int *blen) | 180 | char **bpp, int *blen) |
@@ -198,6 +216,10 @@ static int rsi_parse(struct cache_detail *cd, | |||
198 | if (dup_to_netobj(&rsii.in_token, buf, len)) | 216 | if (dup_to_netobj(&rsii.in_token, buf, len)) |
199 | goto out; | 217 | goto out; |
200 | 218 | ||
219 | rsip = rsi_lookup(&rsii); | ||
220 | if (!rsip) | ||
221 | goto out; | ||
222 | |||
201 | rsii.h.flags = 0; | 223 | rsii.h.flags = 0; |
202 | /* expiry */ | 224 | /* expiry */ |
203 | expiry = get_expiry(&mesg); | 225 | expiry = get_expiry(&mesg); |
@@ -240,12 +262,14 @@ static int rsi_parse(struct cache_detail *cd, | |||
240 | goto out; | 262 | goto out; |
241 | } | 263 | } |
242 | rsii.h.expiry_time = expiry; | 264 | rsii.h.expiry_time = expiry; |
243 | rsip = rsi_lookup(&rsii, 1); | 265 | rsip = rsi_update(&rsii, rsip); |
244 | status = 0; | 266 | status = 0; |
245 | out: | 267 | out: |
246 | rsi_free(&rsii); | 268 | rsi_free(&rsii); |
247 | if (rsip) | 269 | if (rsip) |
248 | rsi_put(&rsip->h, &rsi_cache); | 270 | rsi_put(&rsip->h, &rsi_cache); |
271 | else | ||
272 | status = -ENOMEM; | ||
249 | return status; | 273 | return status; |
250 | } | 274 | } |
251 | 275 | ||
@@ -257,9 +281,37 @@ static struct cache_detail rsi_cache = { | |||
257 | .cache_put = rsi_put, | 281 | .cache_put = rsi_put, |
258 | .cache_request = rsi_request, | 282 | .cache_request = rsi_request, |
259 | .cache_parse = rsi_parse, | 283 | .cache_parse = rsi_parse, |
284 | .match = rsi_match, | ||
285 | .init = rsi_init, | ||
286 | .update = update_rsi, | ||
287 | .alloc = rsi_alloc, | ||
260 | }; | 288 | }; |
261 | 289 | ||
262 | static DefineSimpleCacheLookup(rsi, rsi) | 290 | static struct rsi *rsi_lookup(struct rsi *item) |
291 | { | ||
292 | struct cache_head *ch; | ||
293 | int hash = rsi_hash(item); | ||
294 | |||
295 | ch = sunrpc_cache_lookup(&rsi_cache, &item->h, hash); | ||
296 | if (ch) | ||
297 | return container_of(ch, struct rsi, h); | ||
298 | else | ||
299 | return NULL; | ||
300 | } | ||
301 | |||
302 | static struct rsi *rsi_update(struct rsi *new, struct rsi *old) | ||
303 | { | ||
304 | struct cache_head *ch; | ||
305 | int hash = rsi_hash(new); | ||
306 | |||
307 | ch = sunrpc_cache_update(&rsi_cache, &new->h, | ||
308 | &old->h, hash); | ||
309 | if (ch) | ||
310 | return container_of(ch, struct rsi, h); | ||
311 | else | ||
312 | return NULL; | ||
313 | } | ||
314 | |||
263 | 315 | ||
264 | /* | 316 | /* |
265 | * The rpcsec_context cache is used to store a context that is | 317 | * The rpcsec_context cache is used to store a context that is |
@@ -895,7 +947,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp) | |||
895 | goto drop; | 947 | goto drop; |
896 | } | 948 | } |
897 | 949 | ||
898 | rsip = rsi_lookup(&rsikey, 0); | 950 | rsip = rsi_lookup(&rsikey); |
899 | rsi_free(&rsikey); | 951 | rsi_free(&rsikey); |
900 | if (!rsip) { | 952 | if (!rsip) { |
901 | goto drop; | 953 | goto drop; |