SUNRPC: Faster detection if gssd is actually running
[deliverable/linux.git] / net / sunrpc / auth_gss / auth_gss.c
CommitLineData
1da177e4 1/*
f30c2269 2 * linux/net/sunrpc/auth_gss/auth_gss.c
1da177e4
LT
3 *
4 * RPCSEC_GSS client authentication.
cca5172a 5 *
1da177e4
LT
6 * Copyright (c) 2000 The Regents of the University of Michigan.
7 * All rights reserved.
8 *
9 * Dug Song <dugsong@monkey.org>
10 * Andy Adamson <andros@umich.edu>
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 *
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. Neither the name of the University nor the names of its
22 * contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
26 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
27 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
32 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
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.
1da177e4
LT
36 */
37
38
39#include <linux/module.h>
40#include <linux/init.h>
41#include <linux/types.h>
42#include <linux/slab.h>
1da177e4 43#include <linux/sched.h>
2d2da60c 44#include <linux/pagemap.h>
1da177e4
LT
45#include <linux/sunrpc/clnt.h>
46#include <linux/sunrpc/auth.h>
47#include <linux/sunrpc/auth_gss.h>
48#include <linux/sunrpc/svcauth_gss.h>
49#include <linux/sunrpc/gss_err.h>
50#include <linux/workqueue.h>
51#include <linux/sunrpc/rpc_pipe_fs.h>
52#include <linux/sunrpc/gss_api.h>
53#include <asm/uaccess.h>
54
abfdbd53
TM
55#include "../netns.h"
56
f1c0a861 57static const struct rpc_authops authgss_ops;
1da177e4 58
f1c0a861 59static const struct rpc_credops gss_credops;
0df7fb74 60static const struct rpc_credops gss_nullops;
1da177e4 61
126e216a
TM
62#define GSS_RETRY_EXPIRED 5
63static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED;
64
1da177e4
LT
65#ifdef RPC_DEBUG
66# define RPCDBG_FACILITY RPCDBG_AUTH
67#endif
68
725f2865 69#define GSS_CRED_SLACK (RPC_MAX_AUTH_SIZE * 2)
1da177e4
LT
70/* length of a krb5 verifier (48), plus data added before arguments when
71 * using integrity (two 4-byte integers): */
adeb8133 72#define GSS_VERF_SLACK 100
1da177e4 73
1da177e4 74struct gss_auth {
0285ed1f 75 struct kref kref;
1da177e4
LT
76 struct rpc_auth rpc_auth;
77 struct gss_api_mech *mech;
78 enum rpc_gss_svc service;
1da177e4 79 struct rpc_clnt *client;
34769fc4
BF
80 /*
81 * There are two upcall pipes; dentry[1], named "gssd", is used
82 * for the new text-based upcall; dentry[0] is named after the
83 * mechanism (for example, "krb5") and exists for
84 * backwards-compatibility with older gssd's.
85 */
c239d83b 86 struct rpc_pipe *pipe[2];
1da177e4
LT
87};
88
79a3f20b
BF
89/* pipe_version >= 0 if and only if someone has a pipe open. */
90static int pipe_version = -1;
cf81939d 91static atomic_t pipe_users = ATOMIC_INIT(0);
79a3f20b
BF
92static DEFINE_SPINLOCK(pipe_version_lock);
93static struct rpc_wait_queue pipe_version_rpc_waitqueue;
94static DECLARE_WAIT_QUEUE_HEAD(pipe_version_waitqueue);
cf81939d 95
5d28dc82 96static void gss_free_ctx(struct gss_cl_ctx *);
b693ba4a
TM
97static const struct rpc_pipe_ops gss_upcall_ops_v0;
98static const struct rpc_pipe_ops gss_upcall_ops_v1;
1da177e4 99
1da177e4
LT
100static inline struct gss_cl_ctx *
101gss_get_ctx(struct gss_cl_ctx *ctx)
102{
103 atomic_inc(&ctx->count);
104 return ctx;
105}
106
107static inline void
108gss_put_ctx(struct gss_cl_ctx *ctx)
109{
110 if (atomic_dec_and_test(&ctx->count))
5d28dc82 111 gss_free_ctx(ctx);
1da177e4
LT
112}
113
5d28dc82
TM
114/* gss_cred_set_ctx:
115 * called by gss_upcall_callback and gss_create_upcall in order
116 * to set the gss context. The actual exchange of an old context
9beae467 117 * and a new one is protected by the pipe->lock.
5d28dc82 118 */
1da177e4
LT
119static void
120gss_cred_set_ctx(struct rpc_cred *cred, struct gss_cl_ctx *ctx)
121{
122 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
5d28dc82 123
cd019f75
TM
124 if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags))
125 return;
7b6962b0 126 gss_get_ctx(ctx);
cf778b00 127 rcu_assign_pointer(gss_cred->gc_ctx, ctx);
fc432dd9 128 set_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
cd019f75 129 smp_mb__before_clear_bit();
fc432dd9 130 clear_bit(RPCAUTH_CRED_NEW, &cred->cr_flags);
1da177e4
LT
131}
132
133static const void *
134simple_get_bytes(const void *p, const void *end, void *res, size_t len)
135{
136 const void *q = (const void *)((const char *)p + len);
137 if (unlikely(q > end || q < p))
138 return ERR_PTR(-EFAULT);
139 memcpy(res, p, len);
140 return q;
141}
142
143static inline const void *
144simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest)
145{
146 const void *q;
147 unsigned int len;
148
149 p = simple_get_bytes(p, end, &len, sizeof(len));
150 if (IS_ERR(p))
151 return p;
152 q = (const void *)((const char *)p + len);
153 if (unlikely(q > end || q < p))
154 return ERR_PTR(-EFAULT);
0f38b873 155 dest->data = kmemdup(p, len, GFP_NOFS);
1da177e4
LT
156 if (unlikely(dest->data == NULL))
157 return ERR_PTR(-ENOMEM);
158 dest->len = len;
1da177e4
LT
159 return q;
160}
161
162static struct gss_cl_ctx *
163gss_cred_get_ctx(struct rpc_cred *cred)
164{
165 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
166 struct gss_cl_ctx *ctx = NULL;
167
5d28dc82 168 rcu_read_lock();
1da177e4
LT
169 if (gss_cred->gc_ctx)
170 ctx = gss_get_ctx(gss_cred->gc_ctx);
5d28dc82 171 rcu_read_unlock();
1da177e4
LT
172 return ctx;
173}
174
175static struct gss_cl_ctx *
176gss_alloc_context(void)
177{
178 struct gss_cl_ctx *ctx;
179
0f38b873 180 ctx = kzalloc(sizeof(*ctx), GFP_NOFS);
1da177e4 181 if (ctx != NULL) {
1da177e4
LT
182 ctx->gc_proc = RPC_GSS_PROC_DATA;
183 ctx->gc_seq = 1; /* NetApp 6.4R1 doesn't accept seq. no. 0 */
184 spin_lock_init(&ctx->gc_seq_lock);
185 atomic_set(&ctx->count,1);
186 }
187 return ctx;
188}
189
190#define GSSD_MIN_TIMEOUT (60 * 60)
191static const void *
192gss_fill_context(const void *p, const void *end, struct gss_cl_ctx *ctx, struct gss_api_mech *gm)
193{
194 const void *q;
195 unsigned int seclen;
196 unsigned int timeout;
620038f6 197 unsigned long now = jiffies;
1da177e4
LT
198 u32 window_size;
199 int ret;
200
620038f6
AA
201 /* First unsigned int gives the remaining lifetime in seconds of the
202 * credential - e.g. the remaining TGT lifetime for Kerberos or
203 * the -t value passed to GSSD.
204 */
1da177e4
LT
205 p = simple_get_bytes(p, end, &timeout, sizeof(timeout));
206 if (IS_ERR(p))
207 goto err;
208 if (timeout == 0)
209 timeout = GSSD_MIN_TIMEOUT;
620038f6
AA
210 ctx->gc_expiry = now + ((unsigned long)timeout * HZ);
211 /* Sequence number window. Determines the maximum number of
212 * simultaneous requests
213 */
1da177e4
LT
214 p = simple_get_bytes(p, end, &window_size, sizeof(window_size));
215 if (IS_ERR(p))
216 goto err;
217 ctx->gc_win = window_size;
218 /* gssd signals an error by passing ctx->gc_win = 0: */
219 if (ctx->gc_win == 0) {
dc5ddce9
JL
220 /*
221 * in which case, p points to an error code. Anything other
222 * than -EKEYEXPIRED gets converted to -EACCES.
223 */
224 p = simple_get_bytes(p, end, &ret, sizeof(ret));
225 if (!IS_ERR(p))
226 p = (ret == -EKEYEXPIRED) ? ERR_PTR(-EKEYEXPIRED) :
227 ERR_PTR(-EACCES);
1da177e4
LT
228 goto err;
229 }
230 /* copy the opaque wire context */
231 p = simple_get_netobj(p, end, &ctx->gc_wire_ctx);
232 if (IS_ERR(p))
233 goto err;
234 /* import the opaque security context */
235 p = simple_get_bytes(p, end, &seclen, sizeof(seclen));
236 if (IS_ERR(p))
237 goto err;
238 q = (const void *)((const char *)p + seclen);
239 if (unlikely(q > end || q < p)) {
240 p = ERR_PTR(-EFAULT);
241 goto err;
242 }
400f26b5 243 ret = gss_import_sec_context(p, seclen, gm, &ctx->gc_gss_ctx, NULL, GFP_NOFS);
1da177e4
LT
244 if (ret < 0) {
245 p = ERR_PTR(ret);
246 goto err;
247 }
620038f6
AA
248 dprintk("RPC: %s Success. gc_expiry %lu now %lu timeout %u\n",
249 __func__, ctx->gc_expiry, now, timeout);
1da177e4
LT
250 return q;
251err:
173db309 252 dprintk("RPC: %s returns error %ld\n", __func__, -PTR_ERR(p));
1da177e4
LT
253 return p;
254}
255
34769fc4 256#define UPCALL_BUF_LEN 128
1da177e4
LT
257
258struct gss_upcall_msg {
259 atomic_t count;
7eaf040b 260 kuid_t uid;
1da177e4
LT
261 struct rpc_pipe_msg msg;
262 struct list_head list;
263 struct gss_auth *auth;
9beae467 264 struct rpc_pipe *pipe;
1da177e4
LT
265 struct rpc_wait_queue rpc_waitqueue;
266 wait_queue_head_t waitqueue;
267 struct gss_cl_ctx *ctx;
34769fc4 268 char databuf[UPCALL_BUF_LEN];
1da177e4
LT
269};
270
79a3f20b
BF
271static int get_pipe_version(void)
272{
273 int ret;
274
275 spin_lock(&pipe_version_lock);
276 if (pipe_version >= 0) {
277 atomic_inc(&pipe_users);
34769fc4 278 ret = pipe_version;
79a3f20b
BF
279 } else
280 ret = -EAGAIN;
281 spin_unlock(&pipe_version_lock);
282 return ret;
283}
284
285static void put_pipe_version(void)
286{
287 if (atomic_dec_and_lock(&pipe_users, &pipe_version_lock)) {
288 pipe_version = -1;
289 spin_unlock(&pipe_version_lock);
290 }
291}
292
1da177e4
LT
293static void
294gss_release_msg(struct gss_upcall_msg *gss_msg)
295{
296 if (!atomic_dec_and_test(&gss_msg->count))
297 return;
79a3f20b 298 put_pipe_version();
1da177e4
LT
299 BUG_ON(!list_empty(&gss_msg->list));
300 if (gss_msg->ctx != NULL)
301 gss_put_ctx(gss_msg->ctx);
f6a1cc89 302 rpc_destroy_wait_queue(&gss_msg->rpc_waitqueue);
1da177e4
LT
303 kfree(gss_msg);
304}
305
306static struct gss_upcall_msg *
7eaf040b 307__gss_find_upcall(struct rpc_pipe *pipe, kuid_t uid)
1da177e4
LT
308{
309 struct gss_upcall_msg *pos;
9beae467 310 list_for_each_entry(pos, &pipe->in_downcall, list) {
0b4d51b0 311 if (!uid_eq(pos->uid, uid))
1da177e4
LT
312 continue;
313 atomic_inc(&pos->count);
632f0d05 314 dprintk("RPC: %s found msg %p\n", __func__, pos);
1da177e4
LT
315 return pos;
316 }
632f0d05 317 dprintk("RPC: %s found nothing\n", __func__);
1da177e4
LT
318 return NULL;
319}
320
720b8f2d 321/* Try to add an upcall to the pipefs queue.
1da177e4
LT
322 * If an upcall owned by our uid already exists, then we return a reference
323 * to that upcall instead of adding the new upcall.
324 */
325static inline struct gss_upcall_msg *
053e324f 326gss_add_msg(struct gss_upcall_msg *gss_msg)
1da177e4 327{
9beae467 328 struct rpc_pipe *pipe = gss_msg->pipe;
1da177e4
LT
329 struct gss_upcall_msg *old;
330
9beae467
SK
331 spin_lock(&pipe->lock);
332 old = __gss_find_upcall(pipe, gss_msg->uid);
1da177e4
LT
333 if (old == NULL) {
334 atomic_inc(&gss_msg->count);
9beae467 335 list_add(&gss_msg->list, &pipe->in_downcall);
1da177e4
LT
336 } else
337 gss_msg = old;
9beae467 338 spin_unlock(&pipe->lock);
1da177e4
LT
339 return gss_msg;
340}
341
342static void
343__gss_unhash_msg(struct gss_upcall_msg *gss_msg)
344{
1da177e4
LT
345 list_del_init(&gss_msg->list);
346 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno);
347 wake_up_all(&gss_msg->waitqueue);
348 atomic_dec(&gss_msg->count);
349}
350
351static void
352gss_unhash_msg(struct gss_upcall_msg *gss_msg)
353{
9beae467 354 struct rpc_pipe *pipe = gss_msg->pipe;
1da177e4 355
3b68aaea
TM
356 if (list_empty(&gss_msg->list))
357 return;
9beae467 358 spin_lock(&pipe->lock);
3b68aaea
TM
359 if (!list_empty(&gss_msg->list))
360 __gss_unhash_msg(gss_msg);
9beae467 361 spin_unlock(&pipe->lock);
1da177e4
LT
362}
363
126e216a
TM
364static void
365gss_handle_downcall_result(struct gss_cred *gss_cred, struct gss_upcall_msg *gss_msg)
366{
367 switch (gss_msg->msg.errno) {
368 case 0:
369 if (gss_msg->ctx == NULL)
370 break;
371 clear_bit(RPCAUTH_CRED_NEGATIVE, &gss_cred->gc_base.cr_flags);
372 gss_cred_set_ctx(&gss_cred->gc_base, gss_msg->ctx);
373 break;
374 case -EKEYEXPIRED:
375 set_bit(RPCAUTH_CRED_NEGATIVE, &gss_cred->gc_base.cr_flags);
376 }
377 gss_cred->gc_upcall_timestamp = jiffies;
378 gss_cred->gc_upcall = NULL;
379 rpc_wake_up_status(&gss_msg->rpc_waitqueue, gss_msg->msg.errno);
380}
381
1da177e4
LT
382static void
383gss_upcall_callback(struct rpc_task *task)
384{
a17c2153 385 struct gss_cred *gss_cred = container_of(task->tk_rqstp->rq_cred,
1da177e4
LT
386 struct gss_cred, gc_base);
387 struct gss_upcall_msg *gss_msg = gss_cred->gc_upcall;
9beae467 388 struct rpc_pipe *pipe = gss_msg->pipe;
1da177e4 389
9beae467 390 spin_lock(&pipe->lock);
126e216a 391 gss_handle_downcall_result(gss_cred, gss_msg);
9beae467 392 spin_unlock(&pipe->lock);
126e216a 393 task->tk_status = gss_msg->msg.errno;
1da177e4
LT
394 gss_release_msg(gss_msg);
395}
396
34769fc4
BF
397static void gss_encode_v0_msg(struct gss_upcall_msg *gss_msg)
398{
90602c7b
EB
399 uid_t uid = from_kuid(&init_user_ns, gss_msg->uid);
400 memcpy(gss_msg->databuf, &uid, sizeof(uid));
401 gss_msg->msg.data = gss_msg->databuf;
402 gss_msg->msg.len = sizeof(uid);
403 BUG_ON(sizeof(uid) > UPCALL_BUF_LEN);
34769fc4
BF
404}
405
8b1c7bf5 406static void gss_encode_v1_msg(struct gss_upcall_msg *gss_msg,
68c97153
TM
407 struct rpc_clnt *clnt,
408 const char *service_name)
34769fc4 409{
683ac665 410 struct gss_api_mech *mech = gss_msg->auth->mech;
8b1c7bf5
OK
411 char *p = gss_msg->databuf;
412 int len = 0;
413
414 gss_msg->msg.len = sprintf(gss_msg->databuf, "mech=%s uid=%d ",
683ac665 415 mech->gm_name,
90602c7b 416 from_kuid(&init_user_ns, gss_msg->uid));
8b1c7bf5
OK
417 p += gss_msg->msg.len;
418 if (clnt->cl_principal) {
419 len = sprintf(p, "target=%s ", clnt->cl_principal);
420 p += len;
421 gss_msg->msg.len += len;
422 }
68c97153
TM
423 if (service_name != NULL) {
424 len = sprintf(p, "service=%s ", service_name);
2efef708
OK
425 p += len;
426 gss_msg->msg.len += len;
427 }
683ac665 428 if (mech->gm_upcall_enctypes) {
f8628220 429 len = sprintf(p, "enctypes=%s ", mech->gm_upcall_enctypes);
683ac665
TM
430 p += len;
431 gss_msg->msg.len += len;
432 }
8b1c7bf5
OK
433 len = sprintf(p, "\n");
434 gss_msg->msg.len += len;
435
34769fc4
BF
436 gss_msg->msg.data = gss_msg->databuf;
437 BUG_ON(gss_msg->msg.len > UPCALL_BUF_LEN);
438}
439
8b1c7bf5 440static void gss_encode_msg(struct gss_upcall_msg *gss_msg,
68c97153
TM
441 struct rpc_clnt *clnt,
442 const char *service_name)
34769fc4
BF
443{
444 if (pipe_version == 0)
445 gss_encode_v0_msg(gss_msg);
446 else /* pipe_version == 1 */
68c97153 447 gss_encode_v1_msg(gss_msg, clnt, service_name);
34769fc4
BF
448}
449
68c97153
TM
450static struct gss_upcall_msg *
451gss_alloc_msg(struct gss_auth *gss_auth, struct rpc_clnt *clnt,
7eaf040b 452 kuid_t uid, const char *service_name)
1da177e4
LT
453{
454 struct gss_upcall_msg *gss_msg;
79a3f20b 455 int vers;
1da177e4 456
0f38b873 457 gss_msg = kzalloc(sizeof(*gss_msg), GFP_NOFS);
db75b3d6
BF
458 if (gss_msg == NULL)
459 return ERR_PTR(-ENOMEM);
79a3f20b
BF
460 vers = get_pipe_version();
461 if (vers < 0) {
462 kfree(gss_msg);
463 return ERR_PTR(vers);
464 }
c239d83b 465 gss_msg->pipe = gss_auth->pipe[vers];
db75b3d6
BF
466 INIT_LIST_HEAD(&gss_msg->list);
467 rpc_init_wait_queue(&gss_msg->rpc_waitqueue, "RPCSEC_GSS upcall waitq");
468 init_waitqueue_head(&gss_msg->waitqueue);
469 atomic_set(&gss_msg->count, 1);
db75b3d6
BF
470 gss_msg->uid = uid;
471 gss_msg->auth = gss_auth;
68c97153 472 gss_encode_msg(gss_msg, clnt, service_name);
1da177e4
LT
473 return gss_msg;
474}
475
476static struct gss_upcall_msg *
477gss_setup_upcall(struct rpc_clnt *clnt, struct gss_auth *gss_auth, struct rpc_cred *cred)
478{
7c67db3a
TM
479 struct gss_cred *gss_cred = container_of(cred,
480 struct gss_cred, gc_base);
1da177e4 481 struct gss_upcall_msg *gss_new, *gss_msg;
7eaf040b 482 kuid_t uid = cred->cr_uid;
1da177e4 483
68c97153 484 gss_new = gss_alloc_msg(gss_auth, clnt, uid, gss_cred->gc_principal);
db75b3d6
BF
485 if (IS_ERR(gss_new))
486 return gss_new;
053e324f 487 gss_msg = gss_add_msg(gss_new);
1da177e4 488 if (gss_msg == gss_new) {
9beae467 489 int res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg);
1da177e4
LT
490 if (res) {
491 gss_unhash_msg(gss_new);
492 gss_msg = ERR_PTR(res);
493 }
494 } else
495 gss_release_msg(gss_new);
496 return gss_msg;
497}
498
b03568c3
BF
499static void warn_gssd(void)
500{
501 static unsigned long ratelimit;
502 unsigned long now = jiffies;
503
504 if (time_after(now, ratelimit)) {
505 printk(KERN_WARNING "RPC: AUTH_GSS upcall timed out.\n"
506 "Please check user daemon is running.\n");
507 ratelimit = now + 15*HZ;
508 }
509}
510
1da177e4
LT
511static inline int
512gss_refresh_upcall(struct rpc_task *task)
513{
a17c2153 514 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
4a8c1344 515 struct gss_auth *gss_auth = container_of(cred->cr_auth,
1da177e4
LT
516 struct gss_auth, rpc_auth);
517 struct gss_cred *gss_cred = container_of(cred,
518 struct gss_cred, gc_base);
519 struct gss_upcall_msg *gss_msg;
9beae467 520 struct rpc_pipe *pipe;
1da177e4
LT
521 int err = 0;
522
632f0d05 523 dprintk("RPC: %5u %s for uid %u\n",
cdba321e 524 task->tk_pid, __func__, from_kuid(&init_user_ns, cred->cr_uid));
1da177e4 525 gss_msg = gss_setup_upcall(task->tk_client, gss_auth, cred);
480e3243 526 if (PTR_ERR(gss_msg) == -EAGAIN) {
79a3f20b
BF
527 /* XXX: warning on the first, under the assumption we
528 * shouldn't normally hit this case on a refresh. */
529 warn_gssd();
530 task->tk_timeout = 15*HZ;
531 rpc_sleep_on(&pipe_version_rpc_waitqueue, task, NULL);
d1a8016a 532 return -EAGAIN;
79a3f20b 533 }
1da177e4
LT
534 if (IS_ERR(gss_msg)) {
535 err = PTR_ERR(gss_msg);
536 goto out;
537 }
9beae467
SK
538 pipe = gss_msg->pipe;
539 spin_lock(&pipe->lock);
1da177e4 540 if (gss_cred->gc_upcall != NULL)
5d00837b 541 rpc_sleep_on(&gss_cred->gc_upcall->rpc_waitqueue, task, NULL);
126e216a 542 else if (gss_msg->ctx == NULL && gss_msg->msg.errno >= 0) {
1da177e4
LT
543 task->tk_timeout = 0;
544 gss_cred->gc_upcall = gss_msg;
545 /* gss_upcall_callback will release the reference to gss_upcall_msg */
546 atomic_inc(&gss_msg->count);
5d00837b 547 rpc_sleep_on(&gss_msg->rpc_waitqueue, task, gss_upcall_callback);
126e216a
TM
548 } else {
549 gss_handle_downcall_result(gss_cred, gss_msg);
1da177e4 550 err = gss_msg->msg.errno;
126e216a 551 }
9beae467 552 spin_unlock(&pipe->lock);
1da177e4
LT
553 gss_release_msg(gss_msg);
554out:
632f0d05 555 dprintk("RPC: %5u %s for uid %u result %d\n",
cdba321e
EB
556 task->tk_pid, __func__,
557 from_kuid(&init_user_ns, cred->cr_uid), err);
1da177e4
LT
558 return err;
559}
560
561static inline int
562gss_create_upcall(struct gss_auth *gss_auth, struct gss_cred *gss_cred)
563{
abfdbd53
TM
564 struct net *net = rpc_net_ns(gss_auth->client);
565 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
9beae467 566 struct rpc_pipe *pipe;
1da177e4
LT
567 struct rpc_cred *cred = &gss_cred->gc_base;
568 struct gss_upcall_msg *gss_msg;
abfdbd53 569 unsigned long timeout;
1da177e4 570 DEFINE_WAIT(wait);
d36ccb9c 571 int err;
1da177e4 572
cdba321e
EB
573 dprintk("RPC: %s for uid %u\n",
574 __func__, from_kuid(&init_user_ns, cred->cr_uid));
79a3f20b 575retry:
d36ccb9c 576 err = 0;
abfdbd53
TM
577 /* Default timeout is 15s unless we know that gssd is not running */
578 timeout = 15 * HZ;
579 if (!sn->gssd_running)
580 timeout = HZ >> 2;
1da177e4 581 gss_msg = gss_setup_upcall(gss_auth->client, gss_auth, cred);
79a3f20b
BF
582 if (PTR_ERR(gss_msg) == -EAGAIN) {
583 err = wait_event_interruptible_timeout(pipe_version_waitqueue,
abfdbd53 584 pipe_version >= 0, timeout);
d1a8016a 585 if (pipe_version < 0) {
abfdbd53
TM
586 if (err == 0)
587 sn->gssd_running = 0;
d1a8016a
BS
588 warn_gssd();
589 err = -EACCES;
590 }
d36ccb9c 591 if (err < 0)
79a3f20b 592 goto out;
79a3f20b
BF
593 goto retry;
594 }
1da177e4
LT
595 if (IS_ERR(gss_msg)) {
596 err = PTR_ERR(gss_msg);
597 goto out;
598 }
9beae467 599 pipe = gss_msg->pipe;
1da177e4 600 for (;;) {
5afa9133 601 prepare_to_wait(&gss_msg->waitqueue, &wait, TASK_KILLABLE);
9beae467 602 spin_lock(&pipe->lock);
1da177e4 603 if (gss_msg->ctx != NULL || gss_msg->msg.errno < 0) {
1da177e4
LT
604 break;
605 }
9beae467 606 spin_unlock(&pipe->lock);
5afa9133 607 if (fatal_signal_pending(current)) {
1da177e4
LT
608 err = -ERESTARTSYS;
609 goto out_intr;
610 }
611 schedule();
612 }
613 if (gss_msg->ctx)
7b6962b0 614 gss_cred_set_ctx(cred, gss_msg->ctx);
1da177e4
LT
615 else
616 err = gss_msg->msg.errno;
9beae467 617 spin_unlock(&pipe->lock);
1da177e4
LT
618out_intr:
619 finish_wait(&gss_msg->waitqueue, &wait);
620 gss_release_msg(gss_msg);
621out:
632f0d05 622 dprintk("RPC: %s for uid %u result %d\n",
cdba321e 623 __func__, from_kuid(&init_user_ns, cred->cr_uid), err);
1da177e4
LT
624 return err;
625}
626
1da177e4
LT
627#define MSG_BUF_MAXSIZE 1024
628
629static ssize_t
630gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
631{
632 const void *p, *end;
633 void *buf;
1da177e4 634 struct gss_upcall_msg *gss_msg;
496ad9aa 635 struct rpc_pipe *pipe = RPC_I(file_inode(filp))->pipe;
1da177e4 636 struct gss_cl_ctx *ctx;
90602c7b
EB
637 uid_t id;
638 kuid_t uid;
3b68aaea 639 ssize_t err = -EFBIG;
1da177e4
LT
640
641 if (mlen > MSG_BUF_MAXSIZE)
642 goto out;
643 err = -ENOMEM;
0f38b873 644 buf = kmalloc(mlen, GFP_NOFS);
1da177e4
LT
645 if (!buf)
646 goto out;
647
1da177e4
LT
648 err = -EFAULT;
649 if (copy_from_user(buf, src, mlen))
650 goto err;
651
652 end = (const void *)((char *)buf + mlen);
90602c7b 653 p = simple_get_bytes(buf, end, &id, sizeof(id));
1da177e4
LT
654 if (IS_ERR(p)) {
655 err = PTR_ERR(p);
656 goto err;
657 }
658
90602c7b
EB
659 uid = make_kuid(&init_user_ns, id);
660 if (!uid_valid(uid)) {
661 err = -EINVAL;
662 goto err;
663 }
664
1da177e4
LT
665 err = -ENOMEM;
666 ctx = gss_alloc_context();
667 if (ctx == NULL)
668 goto err;
3b68aaea
TM
669
670 err = -ENOENT;
671 /* Find a matching upcall */
9beae467
SK
672 spin_lock(&pipe->lock);
673 gss_msg = __gss_find_upcall(pipe, uid);
3b68aaea 674 if (gss_msg == NULL) {
9beae467 675 spin_unlock(&pipe->lock);
3b68aaea
TM
676 goto err_put_ctx;
677 }
678 list_del_init(&gss_msg->list);
9beae467 679 spin_unlock(&pipe->lock);
3b68aaea 680
6e84c7b6 681 p = gss_fill_context(p, end, ctx, gss_msg->auth->mech);
1da177e4
LT
682 if (IS_ERR(p)) {
683 err = PTR_ERR(p);
486bad2e
JL
684 switch (err) {
685 case -EACCES:
dc5ddce9 686 case -EKEYEXPIRED:
486bad2e
JL
687 gss_msg->msg.errno = err;
688 err = mlen;
689 break;
690 case -EFAULT:
691 case -ENOMEM:
692 case -EINVAL:
693 case -ENOSYS:
694 gss_msg->msg.errno = -EAGAIN;
695 break;
696 default:
697 printk(KERN_CRIT "%s: bad return from "
6c853099 698 "gss_fill_context: %zd\n", __func__, err);
486bad2e
JL
699 BUG();
700 }
3b68aaea 701 goto err_release_msg;
1da177e4 702 }
3b68aaea
TM
703 gss_msg->ctx = gss_get_ctx(ctx);
704 err = mlen;
705
706err_release_msg:
9beae467 707 spin_lock(&pipe->lock);
3b68aaea 708 __gss_unhash_msg(gss_msg);
9beae467 709 spin_unlock(&pipe->lock);
3b68aaea 710 gss_release_msg(gss_msg);
1da177e4
LT
711err_put_ctx:
712 gss_put_ctx(ctx);
713err:
714 kfree(buf);
715out:
632f0d05 716 dprintk("RPC: %s returning %Zd\n", __func__, err);
1da177e4
LT
717 return err;
718}
719
34769fc4 720static int gss_pipe_open(struct inode *inode, int new_version)
cf81939d 721{
34769fc4
BF
722 int ret = 0;
723
79a3f20b
BF
724 spin_lock(&pipe_version_lock);
725 if (pipe_version < 0) {
34769fc4
BF
726 /* First open of any gss pipe determines the version: */
727 pipe_version = new_version;
79a3f20b
BF
728 rpc_wake_up(&pipe_version_rpc_waitqueue);
729 wake_up(&pipe_version_waitqueue);
34769fc4
BF
730 } else if (pipe_version != new_version) {
731 /* Trying to open a pipe of a different version */
732 ret = -EBUSY;
733 goto out;
79a3f20b 734 }
cf81939d 735 atomic_inc(&pipe_users);
34769fc4 736out:
79a3f20b 737 spin_unlock(&pipe_version_lock);
34769fc4
BF
738 return ret;
739
740}
741
742static int gss_pipe_open_v0(struct inode *inode)
743{
744 return gss_pipe_open(inode, 0);
745}
746
747static int gss_pipe_open_v1(struct inode *inode)
748{
749 return gss_pipe_open(inode, 1);
cf81939d
BF
750}
751
1da177e4
LT
752static void
753gss_pipe_release(struct inode *inode)
754{
9beae467 755 struct rpc_pipe *pipe = RPC_I(inode)->pipe;
6e84c7b6 756 struct gss_upcall_msg *gss_msg;
1da177e4 757
5a67657a 758restart:
9beae467
SK
759 spin_lock(&pipe->lock);
760 list_for_each_entry(gss_msg, &pipe->in_downcall, list) {
1da177e4 761
5a67657a
TM
762 if (!list_empty(&gss_msg->msg.list))
763 continue;
1da177e4
LT
764 gss_msg->msg.errno = -EPIPE;
765 atomic_inc(&gss_msg->count);
766 __gss_unhash_msg(gss_msg);
9beae467 767 spin_unlock(&pipe->lock);
1da177e4 768 gss_release_msg(gss_msg);
5a67657a 769 goto restart;
1da177e4 770 }
9beae467 771 spin_unlock(&pipe->lock);
cf81939d 772
79a3f20b 773 put_pipe_version();
1da177e4
LT
774}
775
776static void
777gss_pipe_destroy_msg(struct rpc_pipe_msg *msg)
778{
779 struct gss_upcall_msg *gss_msg = container_of(msg, struct gss_upcall_msg, msg);
1da177e4
LT
780
781 if (msg->errno < 0) {
632f0d05
CL
782 dprintk("RPC: %s releasing msg %p\n",
783 __func__, gss_msg);
1da177e4
LT
784 atomic_inc(&gss_msg->count);
785 gss_unhash_msg(gss_msg);
b03568c3
BF
786 if (msg->errno == -ETIMEDOUT)
787 warn_gssd();
1da177e4
LT
788 gss_release_msg(gss_msg);
789 }
790}
791
ccdc28f8
SK
792static void gss_pipes_dentries_destroy(struct rpc_auth *auth)
793{
794 struct gss_auth *gss_auth;
795
796 gss_auth = container_of(auth, struct gss_auth, rpc_auth);
80df9d20
SK
797 if (gss_auth->pipe[0]->dentry)
798 rpc_unlink(gss_auth->pipe[0]->dentry);
799 if (gss_auth->pipe[1]->dentry)
800 rpc_unlink(gss_auth->pipe[1]->dentry);
ccdc28f8
SK
801}
802
803static int gss_pipes_dentries_create(struct rpc_auth *auth)
804{
805 int err;
806 struct gss_auth *gss_auth;
807 struct rpc_clnt *clnt;
808
809 gss_auth = container_of(auth, struct gss_auth, rpc_auth);
810 clnt = gss_auth->client;
811
30507f58 812 gss_auth->pipe[1]->dentry = rpc_mkpipe_dentry(clnt->cl_dentry,
ccdc28f8
SK
813 "gssd",
814 clnt, gss_auth->pipe[1]);
815 if (IS_ERR(gss_auth->pipe[1]->dentry))
816 return PTR_ERR(gss_auth->pipe[1]->dentry);
30507f58 817 gss_auth->pipe[0]->dentry = rpc_mkpipe_dentry(clnt->cl_dentry,
ccdc28f8
SK
818 gss_auth->mech->gm_name,
819 clnt, gss_auth->pipe[0]);
820 if (IS_ERR(gss_auth->pipe[0]->dentry)) {
821 err = PTR_ERR(gss_auth->pipe[0]->dentry);
822 goto err_unlink_pipe_1;
823 }
824 return 0;
825
826err_unlink_pipe_1:
827 rpc_unlink(gss_auth->pipe[1]->dentry);
828 return err;
829}
830
831static void gss_pipes_dentries_destroy_net(struct rpc_clnt *clnt,
832 struct rpc_auth *auth)
833{
2446ab60 834 struct net *net = rpc_net_ns(clnt);
ccdc28f8
SK
835 struct super_block *sb;
836
837 sb = rpc_get_sb_net(net);
838 if (sb) {
30507f58 839 if (clnt->cl_dentry)
ccdc28f8
SK
840 gss_pipes_dentries_destroy(auth);
841 rpc_put_sb_net(net);
842 }
843}
844
845static int gss_pipes_dentries_create_net(struct rpc_clnt *clnt,
846 struct rpc_auth *auth)
847{
2446ab60 848 struct net *net = rpc_net_ns(clnt);
ccdc28f8
SK
849 struct super_block *sb;
850 int err = 0;
851
852 sb = rpc_get_sb_net(net);
853 if (sb) {
30507f58 854 if (clnt->cl_dentry)
ccdc28f8
SK
855 err = gss_pipes_dentries_create(auth);
856 rpc_put_sb_net(net);
857 }
858 return err;
859}
860
cca5172a
YH
861/*
862 * NOTE: we have the opportunity to use different
1da177e4
LT
863 * parameters based on the input flavor (which must be a pseudoflavor)
864 */
865static struct rpc_auth *
866gss_create(struct rpc_clnt *clnt, rpc_authflavor_t flavor)
867{
868 struct gss_auth *gss_auth;
869 struct rpc_auth * auth;
6a19275a 870 int err = -ENOMEM; /* XXX? */
1da177e4 871
8885cb36 872 dprintk("RPC: creating GSS authenticator for client %p\n", clnt);
1da177e4
LT
873
874 if (!try_module_get(THIS_MODULE))
6a19275a 875 return ERR_PTR(err);
1da177e4
LT
876 if (!(gss_auth = kmalloc(sizeof(*gss_auth), GFP_KERNEL)))
877 goto out_dec;
878 gss_auth->client = clnt;
6a19275a 879 err = -EINVAL;
1da177e4
LT
880 gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor);
881 if (!gss_auth->mech) {
9b1d75b7 882 dprintk("RPC: Pseudoflavor %d not found!\n", flavor);
1da177e4
LT
883 goto err_free;
884 }
885 gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor);
438b6fde
BF
886 if (gss_auth->service == 0)
887 goto err_put_mech;
1da177e4
LT
888 auth = &gss_auth->rpc_auth;
889 auth->au_cslack = GSS_CRED_SLACK >> 2;
890 auth->au_rslack = GSS_VERF_SLACK >> 2;
891 auth->au_ops = &authgss_ops;
892 auth->au_flavor = flavor;
893 atomic_set(&auth->au_count, 1);
0285ed1f 894 kref_init(&gss_auth->kref);
1da177e4 895
34769fc4
BF
896 /*
897 * Note: if we created the old pipe first, then someone who
898 * examined the directory at the right moment might conclude
899 * that we supported only the old pipe. So we instead create
900 * the new pipe first.
901 */
c239d83b
SK
902 gss_auth->pipe[1] = rpc_mkpipe_data(&gss_upcall_ops_v1,
903 RPC_PIPE_WAIT_FOR_OPEN);
904 if (IS_ERR(gss_auth->pipe[1])) {
905 err = PTR_ERR(gss_auth->pipe[1]);
1da177e4 906 goto err_put_mech;
6a19275a 907 }
1da177e4 908
c239d83b
SK
909 gss_auth->pipe[0] = rpc_mkpipe_data(&gss_upcall_ops_v0,
910 RPC_PIPE_WAIT_FOR_OPEN);
911 if (IS_ERR(gss_auth->pipe[0])) {
912 err = PTR_ERR(gss_auth->pipe[0]);
913 goto err_destroy_pipe_1;
914 }
ccdc28f8
SK
915 err = gss_pipes_dentries_create_net(clnt, auth);
916 if (err)
c239d83b 917 goto err_destroy_pipe_0;
f5c2187c 918 err = rpcauth_init_credcache(auth);
07a2bf1d 919 if (err)
ccdc28f8 920 goto err_unlink_pipes;
07a2bf1d 921
1da177e4 922 return auth;
ccdc28f8
SK
923err_unlink_pipes:
924 gss_pipes_dentries_destroy_net(clnt, auth);
c239d83b
SK
925err_destroy_pipe_0:
926 rpc_destroy_pipe_data(gss_auth->pipe[0]);
927err_destroy_pipe_1:
928 rpc_destroy_pipe_data(gss_auth->pipe[1]);
1da177e4
LT
929err_put_mech:
930 gss_mech_put(gss_auth->mech);
931err_free:
932 kfree(gss_auth);
933out_dec:
934 module_put(THIS_MODULE);
6a19275a 935 return ERR_PTR(err);
1da177e4
LT
936}
937
0285ed1f
TM
938static void
939gss_free(struct gss_auth *gss_auth)
940{
ccdc28f8 941 gss_pipes_dentries_destroy_net(gss_auth->client, &gss_auth->rpc_auth);
c239d83b
SK
942 rpc_destroy_pipe_data(gss_auth->pipe[0]);
943 rpc_destroy_pipe_data(gss_auth->pipe[1]);
0285ed1f
TM
944 gss_mech_put(gss_auth->mech);
945
946 kfree(gss_auth);
947 module_put(THIS_MODULE);
948}
949
950static void
951gss_free_callback(struct kref *kref)
952{
953 struct gss_auth *gss_auth = container_of(kref, struct gss_auth, kref);
954
955 gss_free(gss_auth);
956}
957
1da177e4
LT
958static void
959gss_destroy(struct rpc_auth *auth)
960{
961 struct gss_auth *gss_auth;
962
8885cb36
CL
963 dprintk("RPC: destroying GSS authenticator %p flavor %d\n",
964 auth, auth->au_flavor);
1da177e4 965
3ab9bb72
TM
966 rpcauth_destroy_credcache(auth);
967
1da177e4 968 gss_auth = container_of(auth, struct gss_auth, rpc_auth);
0285ed1f 969 kref_put(&gss_auth->kref, gss_free_callback);
1da177e4
LT
970}
971
0df7fb74
TM
972/*
973 * gss_destroying_context will cause the RPCSEC_GSS to send a NULL RPC call
974 * to the server with the GSS control procedure field set to
975 * RPC_GSS_PROC_DESTROY. This should normally cause the server to release
976 * all RPCSEC_GSS state associated with that context.
977 */
978static int
979gss_destroying_context(struct rpc_cred *cred)
980{
981 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
982 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth);
983 struct rpc_task *task;
984
985 if (gss_cred->gc_ctx == NULL ||
6dcd3926 986 test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags) == 0)
0df7fb74
TM
987 return 0;
988
989 gss_cred->gc_ctx->gc_proc = RPC_GSS_PROC_DESTROY;
990 cred->cr_ops = &gss_nullops;
991
992 /* Take a reference to ensure the cred will be destroyed either
993 * by the RPC call or by the put_rpccred() below */
994 get_rpccred(cred);
995
080a1f14 996 task = rpc_call_null(gss_auth->client, cred, RPC_TASK_ASYNC|RPC_TASK_SOFT);
0df7fb74
TM
997 if (!IS_ERR(task))
998 rpc_put_task(task);
999
1000 put_rpccred(cred);
1001 return 1;
1002}
1003
1004/* gss_destroy_cred (and gss_free_ctx) are used to clean up after failure
1da177e4
LT
1005 * to create a new cred or context, so they check that things have been
1006 * allocated before freeing them. */
1007static void
5d28dc82 1008gss_do_free_ctx(struct gss_cl_ctx *ctx)
1da177e4 1009{
632f0d05 1010 dprintk("RPC: %s\n", __func__);
1da177e4 1011
0d8a3746 1012 gss_delete_sec_context(&ctx->gc_gss_ctx);
1da177e4
LT
1013 kfree(ctx->gc_wire_ctx.data);
1014 kfree(ctx);
1015}
1016
5d28dc82
TM
1017static void
1018gss_free_ctx_callback(struct rcu_head *head)
1019{
1020 struct gss_cl_ctx *ctx = container_of(head, struct gss_cl_ctx, gc_rcu);
1021 gss_do_free_ctx(ctx);
1022}
1023
1024static void
1025gss_free_ctx(struct gss_cl_ctx *ctx)
1026{
1027 call_rcu(&ctx->gc_rcu, gss_free_ctx_callback);
1028}
1029
1da177e4 1030static void
31be5bf1 1031gss_free_cred(struct gss_cred *gss_cred)
1da177e4 1032{
632f0d05 1033 dprintk("RPC: %s cred=%p\n", __func__, gss_cred);
31be5bf1
TM
1034 kfree(gss_cred);
1035}
1da177e4 1036
31be5bf1
TM
1037static void
1038gss_free_cred_callback(struct rcu_head *head)
1039{
1040 struct gss_cred *gss_cred = container_of(head, struct gss_cred, gc_base.cr_rcu);
1041 gss_free_cred(gss_cred);
1042}
1da177e4 1043
31be5bf1 1044static void
6dcd3926 1045gss_destroy_nullcred(struct rpc_cred *cred)
31be5bf1 1046{
5d28dc82 1047 struct gss_cred *gss_cred = container_of(cred, struct gss_cred, gc_base);
0285ed1f 1048 struct gss_auth *gss_auth = container_of(cred->cr_auth, struct gss_auth, rpc_auth);
5d28dc82
TM
1049 struct gss_cl_ctx *ctx = gss_cred->gc_ctx;
1050
a9b3cd7f 1051 RCU_INIT_POINTER(gss_cred->gc_ctx, NULL);
31be5bf1 1052 call_rcu(&cred->cr_rcu, gss_free_cred_callback);
5d28dc82
TM
1053 if (ctx)
1054 gss_put_ctx(ctx);
0285ed1f 1055 kref_put(&gss_auth->kref, gss_free_callback);
1da177e4
LT
1056}
1057
6dcd3926
JL
1058static void
1059gss_destroy_cred(struct rpc_cred *cred)
1060{
1061
1062 if (gss_destroying_context(cred))
1063 return;
1064 gss_destroy_nullcred(cred);
1065}
1066
1da177e4
LT
1067/*
1068 * Lookup RPCSEC_GSS cred for the current process
1069 */
1070static struct rpc_cred *
8a317760 1071gss_lookup_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
1da177e4 1072{
8a317760 1073 return rpcauth_lookup_credcache(auth, acred, flags);
1da177e4
LT
1074}
1075
1076static struct rpc_cred *
8a317760 1077gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
1da177e4
LT
1078{
1079 struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth);
1080 struct gss_cred *cred = NULL;
1081 int err = -ENOMEM;
1082
632f0d05 1083 dprintk("RPC: %s for uid %d, flavor %d\n",
cdba321e
EB
1084 __func__, from_kuid(&init_user_ns, acred->uid),
1085 auth->au_flavor);
1da177e4 1086
0f38b873 1087 if (!(cred = kzalloc(sizeof(*cred), GFP_NOFS)))
1da177e4
LT
1088 goto out_err;
1089
5fe4755e 1090 rpcauth_init_cred(&cred->gc_base, acred, auth, &gss_credops);
1da177e4
LT
1091 /*
1092 * Note: in order to force a call to call_refresh(), we deliberately
1093 * fail to flag the credential as RPCAUTH_CRED_UPTODATE.
1094 */
fc432dd9 1095 cred->gc_base.cr_flags = 1UL << RPCAUTH_CRED_NEW;
1da177e4 1096 cred->gc_service = gss_auth->service;
68c97153
TM
1097 cred->gc_principal = NULL;
1098 if (acred->machine_cred)
1099 cred->gc_principal = acred->principal;
0285ed1f 1100 kref_get(&gss_auth->kref);
1da177e4
LT
1101 return &cred->gc_base;
1102
1103out_err:
632f0d05 1104 dprintk("RPC: %s failed with error %d\n", __func__, err);
1da177e4
LT
1105 return ERR_PTR(err);
1106}
1107
fba3bad4
TM
1108static int
1109gss_cred_init(struct rpc_auth *auth, struct rpc_cred *cred)
1110{
1111 struct gss_auth *gss_auth = container_of(auth, struct gss_auth, rpc_auth);
1112 struct gss_cred *gss_cred = container_of(cred,struct gss_cred, gc_base);
1113 int err;
1114
1115 do {
1116 err = gss_create_upcall(gss_auth, gss_cred);
1117 } while (err == -EAGAIN);
1118 return err;
1119}
1120
1da177e4 1121static int
8a317760 1122gss_match(struct auth_cred *acred, struct rpc_cred *rc, int flags)
1da177e4
LT
1123{
1124 struct gss_cred *gss_cred = container_of(rc, struct gss_cred, gc_base);
1125
cd019f75 1126 if (test_bit(RPCAUTH_CRED_NEW, &rc->cr_flags))
8a317760 1127 goto out;
1da177e4 1128 /* Don't match with creds that have expired. */
cd019f75
TM
1129 if (time_after(jiffies, gss_cred->gc_ctx->gc_expiry))
1130 return 0;
1131 if (!test_bit(RPCAUTH_CRED_UPTODATE, &rc->cr_flags))
1da177e4 1132 return 0;
8a317760 1133out:
68c97153
TM
1134 if (acred->principal != NULL) {
1135 if (gss_cred->gc_principal == NULL)
1136 return 0;
1137 return strcmp(acred->principal, gss_cred->gc_principal) == 0;
1138 }
1139 if (gss_cred->gc_principal != NULL)
7c67db3a 1140 return 0;
0b4d51b0 1141 return uid_eq(rc->cr_uid, acred->uid);
1da177e4
LT
1142}
1143
1144/*
1145* Marshal credentials.
1146* Maybe we should keep a cached credential for performance reasons.
1147*/
d8ed029d
AD
1148static __be32 *
1149gss_marshal(struct rpc_task *task, __be32 *p)
1da177e4 1150{
a17c2153
TM
1151 struct rpc_rqst *req = task->tk_rqstp;
1152 struct rpc_cred *cred = req->rq_cred;
1da177e4
LT
1153 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1154 gc_base);
1155 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
d8ed029d 1156 __be32 *cred_len;
1da177e4
LT
1157 u32 maj_stat = 0;
1158 struct xdr_netobj mic;
1159 struct kvec iov;
1160 struct xdr_buf verf_buf;
1161
632f0d05 1162 dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
1da177e4
LT
1163
1164 *p++ = htonl(RPC_AUTH_GSS);
1165 cred_len = p++;
1166
1167 spin_lock(&ctx->gc_seq_lock);
1168 req->rq_seqno = ctx->gc_seq++;
1169 spin_unlock(&ctx->gc_seq_lock);
1170
1171 *p++ = htonl((u32) RPC_GSS_VERSION);
1172 *p++ = htonl((u32) ctx->gc_proc);
1173 *p++ = htonl((u32) req->rq_seqno);
1174 *p++ = htonl((u32) gss_cred->gc_service);
1175 p = xdr_encode_netobj(p, &ctx->gc_wire_ctx);
1176 *cred_len = htonl((p - (cred_len + 1)) << 2);
1177
1178 /* We compute the checksum for the verifier over the xdr-encoded bytes
1179 * starting with the xid and ending at the end of the credential: */
a4f0835c 1180 iov.iov_base = xprt_skip_transport_header(req->rq_xprt,
808012fb 1181 req->rq_snd_buf.head[0].iov_base);
1da177e4
LT
1182 iov.iov_len = (u8 *)p - (u8 *)iov.iov_base;
1183 xdr_buf_from_iov(&iov, &verf_buf);
1184
1185 /* set verifier flavor*/
1186 *p++ = htonl(RPC_AUTH_GSS);
1187
1188 mic.data = (u8 *)(p + 1);
00fd6e14 1189 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
1da177e4 1190 if (maj_stat == GSS_S_CONTEXT_EXPIRED) {
fc432dd9 1191 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1da177e4
LT
1192 } else if (maj_stat != 0) {
1193 printk("gss_marshal: gss_get_mic FAILED (%d)\n", maj_stat);
1194 goto out_put_ctx;
1195 }
1196 p = xdr_encode_opaque(p, NULL, mic.len);
1197 gss_put_ctx(ctx);
1198 return p;
1199out_put_ctx:
1200 gss_put_ctx(ctx);
1201 return NULL;
1202}
1203
cd019f75
TM
1204static int gss_renew_cred(struct rpc_task *task)
1205{
a17c2153 1206 struct rpc_cred *oldcred = task->tk_rqstp->rq_cred;
cd019f75
TM
1207 struct gss_cred *gss_cred = container_of(oldcred,
1208 struct gss_cred,
1209 gc_base);
1210 struct rpc_auth *auth = oldcred->cr_auth;
1211 struct auth_cred acred = {
1212 .uid = oldcred->cr_uid,
68c97153
TM
1213 .principal = gss_cred->gc_principal,
1214 .machine_cred = (gss_cred->gc_principal != NULL ? 1 : 0),
cd019f75
TM
1215 };
1216 struct rpc_cred *new;
1217
1218 new = gss_lookup_cred(auth, &acred, RPCAUTH_LOOKUP_NEW);
1219 if (IS_ERR(new))
1220 return PTR_ERR(new);
a17c2153 1221 task->tk_rqstp->rq_cred = new;
cd019f75
TM
1222 put_rpccred(oldcred);
1223 return 0;
1224}
1225
126e216a
TM
1226static int gss_cred_is_negative_entry(struct rpc_cred *cred)
1227{
1228 if (test_bit(RPCAUTH_CRED_NEGATIVE, &cred->cr_flags)) {
1229 unsigned long now = jiffies;
1230 unsigned long begin, expire;
1231 struct gss_cred *gss_cred;
1232
1233 gss_cred = container_of(cred, struct gss_cred, gc_base);
1234 begin = gss_cred->gc_upcall_timestamp;
1235 expire = begin + gss_expired_cred_retry_delay * HZ;
1236
1237 if (time_in_range_open(now, begin, expire))
1238 return 1;
1239 }
1240 return 0;
1241}
1242
1da177e4
LT
1243/*
1244* Refresh credentials. XXX - finish
1245*/
1246static int
1247gss_refresh(struct rpc_task *task)
1248{
a17c2153 1249 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
cd019f75
TM
1250 int ret = 0;
1251
126e216a
TM
1252 if (gss_cred_is_negative_entry(cred))
1253 return -EKEYEXPIRED;
1254
cd019f75
TM
1255 if (!test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags) &&
1256 !test_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags)) {
1257 ret = gss_renew_cred(task);
1258 if (ret < 0)
1259 goto out;
a17c2153 1260 cred = task->tk_rqstp->rq_cred;
cd019f75 1261 }
1da177e4 1262
cd019f75
TM
1263 if (test_bit(RPCAUTH_CRED_NEW, &cred->cr_flags))
1264 ret = gss_refresh_upcall(task);
1265out:
1266 return ret;
1da177e4
LT
1267}
1268
0df7fb74
TM
1269/* Dummy refresh routine: used only when destroying the context */
1270static int
1271gss_refresh_null(struct rpc_task *task)
1272{
1273 return -EACCES;
1274}
1275
d8ed029d
AD
1276static __be32 *
1277gss_validate(struct rpc_task *task, __be32 *p)
1da177e4 1278{
a17c2153 1279 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1da177e4 1280 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
d8ed029d 1281 __be32 seq;
1da177e4
LT
1282 struct kvec iov;
1283 struct xdr_buf verf_buf;
1284 struct xdr_netobj mic;
1285 u32 flav,len;
1286 u32 maj_stat;
1287
632f0d05 1288 dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
1da177e4
LT
1289
1290 flav = ntohl(*p++);
1291 if ((len = ntohl(*p++)) > RPC_MAX_AUTH_SIZE)
cca5172a 1292 goto out_bad;
1da177e4
LT
1293 if (flav != RPC_AUTH_GSS)
1294 goto out_bad;
1295 seq = htonl(task->tk_rqstp->rq_seqno);
1296 iov.iov_base = &seq;
1297 iov.iov_len = sizeof(seq);
1298 xdr_buf_from_iov(&iov, &verf_buf);
1299 mic.data = (u8 *)p;
1300 mic.len = len;
1301
00fd6e14 1302 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &verf_buf, &mic);
1da177e4 1303 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
fc432dd9 1304 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
0df7fb74 1305 if (maj_stat) {
632f0d05
CL
1306 dprintk("RPC: %5u %s: gss_verify_mic returned error 0x%08x\n",
1307 task->tk_pid, __func__, maj_stat);
1da177e4 1308 goto out_bad;
0df7fb74 1309 }
24b2605b
BF
1310 /* We leave it to unwrap to calculate au_rslack. For now we just
1311 * calculate the length of the verifier: */
1be27f36 1312 cred->cr_auth->au_verfsize = XDR_QUADLEN(len) + 2;
1da177e4 1313 gss_put_ctx(ctx);
632f0d05
CL
1314 dprintk("RPC: %5u %s: gss_verify_mic succeeded.\n",
1315 task->tk_pid, __func__);
1da177e4
LT
1316 return p + XDR_QUADLEN(len);
1317out_bad:
1318 gss_put_ctx(ctx);
632f0d05 1319 dprintk("RPC: %5u %s failed.\n", task->tk_pid, __func__);
1da177e4
LT
1320 return NULL;
1321}
1322
9f06c719
CL
1323static void gss_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp,
1324 __be32 *p, void *obj)
1325{
1326 struct xdr_stream xdr;
1327
1328 xdr_init_encode(&xdr, &rqstp->rq_snd_buf, p);
1329 encode(rqstp, &xdr, obj);
1330}
1331
1da177e4
LT
1332static inline int
1333gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
9f06c719
CL
1334 kxdreproc_t encode, struct rpc_rqst *rqstp,
1335 __be32 *p, void *obj)
1da177e4
LT
1336{
1337 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
1338 struct xdr_buf integ_buf;
d8ed029d 1339 __be32 *integ_len = NULL;
1da177e4 1340 struct xdr_netobj mic;
d8ed029d
AD
1341 u32 offset;
1342 __be32 *q;
1da177e4
LT
1343 struct kvec *iov;
1344 u32 maj_stat = 0;
1345 int status = -EIO;
1346
1347 integ_len = p++;
1348 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
1349 *p++ = htonl(rqstp->rq_seqno);
1350
9f06c719 1351 gss_wrap_req_encode(encode, rqstp, p, obj);
1da177e4
LT
1352
1353 if (xdr_buf_subsegment(snd_buf, &integ_buf,
1354 offset, snd_buf->len - offset))
1355 return status;
1356 *integ_len = htonl(integ_buf.len);
1357
1358 /* guess whether we're in the head or the tail: */
cca5172a 1359 if (snd_buf->page_len || snd_buf->tail[0].iov_len)
1da177e4
LT
1360 iov = snd_buf->tail;
1361 else
1362 iov = snd_buf->head;
1363 p = iov->iov_base + iov->iov_len;
1364 mic.data = (u8 *)(p + 1);
1365
00fd6e14 1366 maj_stat = gss_get_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
1da177e4
LT
1367 status = -EIO; /* XXX? */
1368 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
fc432dd9 1369 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1da177e4
LT
1370 else if (maj_stat)
1371 return status;
1372 q = xdr_encode_opaque(p, NULL, mic.len);
1373
1374 offset = (u8 *)q - (u8 *)p;
1375 iov->iov_len += offset;
1376 snd_buf->len += offset;
1377 return 0;
1378}
1379
2d2da60c
BF
1380static void
1381priv_release_snd_buf(struct rpc_rqst *rqstp)
1382{
1383 int i;
1384
1385 for (i=0; i < rqstp->rq_enc_pages_num; i++)
1386 __free_page(rqstp->rq_enc_pages[i]);
1387 kfree(rqstp->rq_enc_pages);
1388}
1389
1390static int
1391alloc_enc_pages(struct rpc_rqst *rqstp)
1392{
1393 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
1394 int first, last, i;
1395
1396 if (snd_buf->page_len == 0) {
1397 rqstp->rq_enc_pages_num = 0;
1398 return 0;
1399 }
1400
1401 first = snd_buf->page_base >> PAGE_CACHE_SHIFT;
1402 last = (snd_buf->page_base + snd_buf->page_len - 1) >> PAGE_CACHE_SHIFT;
1403 rqstp->rq_enc_pages_num = last - first + 1 + 1;
1404 rqstp->rq_enc_pages
1405 = kmalloc(rqstp->rq_enc_pages_num * sizeof(struct page *),
1406 GFP_NOFS);
1407 if (!rqstp->rq_enc_pages)
1408 goto out;
1409 for (i=0; i < rqstp->rq_enc_pages_num; i++) {
1410 rqstp->rq_enc_pages[i] = alloc_page(GFP_NOFS);
1411 if (rqstp->rq_enc_pages[i] == NULL)
1412 goto out_free;
1413 }
1414 rqstp->rq_release_snd_buf = priv_release_snd_buf;
1415 return 0;
1416out_free:
cdead7cf
TM
1417 rqstp->rq_enc_pages_num = i;
1418 priv_release_snd_buf(rqstp);
2d2da60c
BF
1419out:
1420 return -EAGAIN;
1421}
1422
1423static inline int
1424gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
9f06c719
CL
1425 kxdreproc_t encode, struct rpc_rqst *rqstp,
1426 __be32 *p, void *obj)
2d2da60c
BF
1427{
1428 struct xdr_buf *snd_buf = &rqstp->rq_snd_buf;
1429 u32 offset;
1430 u32 maj_stat;
1431 int status;
d8ed029d 1432 __be32 *opaque_len;
2d2da60c
BF
1433 struct page **inpages;
1434 int first;
1435 int pad;
1436 struct kvec *iov;
1437 char *tmp;
1438
1439 opaque_len = p++;
1440 offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base;
1441 *p++ = htonl(rqstp->rq_seqno);
1442
9f06c719 1443 gss_wrap_req_encode(encode, rqstp, p, obj);
2d2da60c
BF
1444
1445 status = alloc_enc_pages(rqstp);
1446 if (status)
1447 return status;
1448 first = snd_buf->page_base >> PAGE_CACHE_SHIFT;
1449 inpages = snd_buf->pages + first;
1450 snd_buf->pages = rqstp->rq_enc_pages;
1451 snd_buf->page_base -= first << PAGE_CACHE_SHIFT;
7561042f
KC
1452 /*
1453 * Give the tail its own page, in case we need extra space in the
1454 * head when wrapping:
1455 *
1456 * call_allocate() allocates twice the slack space required
1457 * by the authentication flavor to rq_callsize.
1458 * For GSS, slack is GSS_CRED_SLACK.
1459 */
2d2da60c
BF
1460 if (snd_buf->page_len || snd_buf->tail[0].iov_len) {
1461 tmp = page_address(rqstp->rq_enc_pages[rqstp->rq_enc_pages_num - 1]);
1462 memcpy(tmp, snd_buf->tail[0].iov_base, snd_buf->tail[0].iov_len);
1463 snd_buf->tail[0].iov_base = tmp;
1464 }
00fd6e14 1465 maj_stat = gss_wrap(ctx->gc_gss_ctx, offset, snd_buf, inpages);
7561042f 1466 /* slack space should prevent this ever happening: */
2d2da60c 1467 BUG_ON(snd_buf->len > snd_buf->buflen);
cca5172a 1468 status = -EIO;
2d2da60c
BF
1469 /* We're assuming that when GSS_S_CONTEXT_EXPIRED, the encryption was
1470 * done anyway, so it's safe to put the request on the wire: */
1471 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
fc432dd9 1472 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
2d2da60c
BF
1473 else if (maj_stat)
1474 return status;
1475
1476 *opaque_len = htonl(snd_buf->len - offset);
1477 /* guess whether we're in the head or the tail: */
1478 if (snd_buf->page_len || snd_buf->tail[0].iov_len)
1479 iov = snd_buf->tail;
1480 else
1481 iov = snd_buf->head;
1482 p = iov->iov_base + iov->iov_len;
1483 pad = 3 - ((snd_buf->len - offset - 1) & 3);
1484 memset(p, 0, pad);
1485 iov->iov_len += pad;
1486 snd_buf->len += pad;
1487
1488 return 0;
1489}
1490
1da177e4
LT
1491static int
1492gss_wrap_req(struct rpc_task *task,
9f06c719 1493 kxdreproc_t encode, void *rqstp, __be32 *p, void *obj)
1da177e4 1494{
a17c2153 1495 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1da177e4
LT
1496 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1497 gc_base);
1498 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
1499 int status = -EIO;
1500
632f0d05 1501 dprintk("RPC: %5u %s\n", task->tk_pid, __func__);
1da177e4
LT
1502 if (ctx->gc_proc != RPC_GSS_PROC_DATA) {
1503 /* The spec seems a little ambiguous here, but I think that not
1504 * wrapping context destruction requests makes the most sense.
1505 */
9f06c719
CL
1506 gss_wrap_req_encode(encode, rqstp, p, obj);
1507 status = 0;
1da177e4
LT
1508 goto out;
1509 }
1510 switch (gss_cred->gc_service) {
89f0e4fe
JP
1511 case RPC_GSS_SVC_NONE:
1512 gss_wrap_req_encode(encode, rqstp, p, obj);
1513 status = 0;
1514 break;
1515 case RPC_GSS_SVC_INTEGRITY:
1516 status = gss_wrap_req_integ(cred, ctx, encode, rqstp, p, obj);
1517 break;
1518 case RPC_GSS_SVC_PRIVACY:
1519 status = gss_wrap_req_priv(cred, ctx, encode, rqstp, p, obj);
1520 break;
1da177e4
LT
1521 }
1522out:
1523 gss_put_ctx(ctx);
632f0d05 1524 dprintk("RPC: %5u %s returning %d\n", task->tk_pid, __func__, status);
1da177e4
LT
1525 return status;
1526}
1527
1528static inline int
1529gss_unwrap_resp_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
d8ed029d 1530 struct rpc_rqst *rqstp, __be32 **p)
1da177e4
LT
1531{
1532 struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
1533 struct xdr_buf integ_buf;
1534 struct xdr_netobj mic;
1535 u32 data_offset, mic_offset;
1536 u32 integ_len;
1537 u32 maj_stat;
1538 int status = -EIO;
1539
1540 integ_len = ntohl(*(*p)++);
1541 if (integ_len & 3)
1542 return status;
1543 data_offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base;
1544 mic_offset = integ_len + data_offset;
1545 if (mic_offset > rcv_buf->len)
1546 return status;
1547 if (ntohl(*(*p)++) != rqstp->rq_seqno)
1548 return status;
1549
1550 if (xdr_buf_subsegment(rcv_buf, &integ_buf, data_offset,
1551 mic_offset - data_offset))
1552 return status;
1553
1554 if (xdr_buf_read_netobj(rcv_buf, &mic, mic_offset))
1555 return status;
1556
00fd6e14 1557 maj_stat = gss_verify_mic(ctx->gc_gss_ctx, &integ_buf, &mic);
1da177e4 1558 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
fc432dd9 1559 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
1da177e4
LT
1560 if (maj_stat != GSS_S_COMPLETE)
1561 return status;
1562 return 0;
1563}
1564
2d2da60c
BF
1565static inline int
1566gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx,
d8ed029d 1567 struct rpc_rqst *rqstp, __be32 **p)
2d2da60c
BF
1568{
1569 struct xdr_buf *rcv_buf = &rqstp->rq_rcv_buf;
1570 u32 offset;
1571 u32 opaque_len;
1572 u32 maj_stat;
1573 int status = -EIO;
1574
1575 opaque_len = ntohl(*(*p)++);
1576 offset = (u8 *)(*p) - (u8 *)rcv_buf->head[0].iov_base;
1577 if (offset + opaque_len > rcv_buf->len)
1578 return status;
1579 /* remove padding: */
1580 rcv_buf->len = offset + opaque_len;
1581
00fd6e14 1582 maj_stat = gss_unwrap(ctx->gc_gss_ctx, offset, rcv_buf);
2d2da60c 1583 if (maj_stat == GSS_S_CONTEXT_EXPIRED)
fc432dd9 1584 clear_bit(RPCAUTH_CRED_UPTODATE, &cred->cr_flags);
2d2da60c
BF
1585 if (maj_stat != GSS_S_COMPLETE)
1586 return status;
1587 if (ntohl(*(*p)++) != rqstp->rq_seqno)
1588 return status;
1589
1590 return 0;
1591}
1592
bf269551
CL
1593static int
1594gss_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp,
1595 __be32 *p, void *obj)
1596{
1597 struct xdr_stream xdr;
1598
1599 xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p);
1600 return decode(rqstp, &xdr, obj);
1601}
2d2da60c 1602
1da177e4
LT
1603static int
1604gss_unwrap_resp(struct rpc_task *task,
bf269551 1605 kxdrdproc_t decode, void *rqstp, __be32 *p, void *obj)
1da177e4 1606{
a17c2153 1607 struct rpc_cred *cred = task->tk_rqstp->rq_cred;
1da177e4
LT
1608 struct gss_cred *gss_cred = container_of(cred, struct gss_cred,
1609 gc_base);
1610 struct gss_cl_ctx *ctx = gss_cred_get_ctx(cred);
d8ed029d 1611 __be32 *savedp = p;
2d2da60c
BF
1612 struct kvec *head = ((struct rpc_rqst *)rqstp)->rq_rcv_buf.head;
1613 int savedlen = head->iov_len;
1da177e4
LT
1614 int status = -EIO;
1615
1616 if (ctx->gc_proc != RPC_GSS_PROC_DATA)
1617 goto out_decode;
1618 switch (gss_cred->gc_service) {
89f0e4fe
JP
1619 case RPC_GSS_SVC_NONE:
1620 break;
1621 case RPC_GSS_SVC_INTEGRITY:
1622 status = gss_unwrap_resp_integ(cred, ctx, rqstp, &p);
1623 if (status)
1624 goto out;
1625 break;
1626 case RPC_GSS_SVC_PRIVACY:
1627 status = gss_unwrap_resp_priv(cred, ctx, rqstp, &p);
1628 if (status)
1629 goto out;
1630 break;
1da177e4 1631 }
24b2605b 1632 /* take into account extra slack for integrity and privacy cases: */
1be27f36 1633 cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp)
2d2da60c 1634 + (savedlen - head->iov_len);
1da177e4 1635out_decode:
bf269551 1636 status = gss_unwrap_req_decode(decode, rqstp, p, obj);
1da177e4
LT
1637out:
1638 gss_put_ctx(ctx);
632f0d05
CL
1639 dprintk("RPC: %5u %s returning %d\n",
1640 task->tk_pid, __func__, status);
1da177e4
LT
1641 return status;
1642}
cca5172a 1643
f1c0a861 1644static const struct rpc_authops authgss_ops = {
1da177e4
LT
1645 .owner = THIS_MODULE,
1646 .au_flavor = RPC_AUTH_GSS,
1da177e4 1647 .au_name = "RPCSEC_GSS",
1da177e4
LT
1648 .create = gss_create,
1649 .destroy = gss_destroy,
1650 .lookup_cred = gss_lookup_cred,
80df9d20
SK
1651 .crcreate = gss_create_cred,
1652 .pipes_create = gss_pipes_dentries_create,
1653 .pipes_destroy = gss_pipes_dentries_destroy,
6a1a1e34 1654 .list_pseudoflavors = gss_mech_list_pseudoflavors,
9568c5e9 1655 .info2flavor = gss_mech_info2flavor,
a77c806f 1656 .flavor2info = gss_mech_flavor2info,
1da177e4
LT
1657};
1658
f1c0a861 1659static const struct rpc_credops gss_credops = {
1da177e4
LT
1660 .cr_name = "AUTH_GSS",
1661 .crdestroy = gss_destroy_cred,
fba3bad4 1662 .cr_init = gss_cred_init,
5c691044 1663 .crbind = rpcauth_generic_bind_cred,
1da177e4
LT
1664 .crmatch = gss_match,
1665 .crmarshal = gss_marshal,
1666 .crrefresh = gss_refresh,
1667 .crvalidate = gss_validate,
1668 .crwrap_req = gss_wrap_req,
1669 .crunwrap_resp = gss_unwrap_resp,
1670};
1671
0df7fb74
TM
1672static const struct rpc_credops gss_nullops = {
1673 .cr_name = "AUTH_GSS",
6dcd3926 1674 .crdestroy = gss_destroy_nullcred,
5c691044 1675 .crbind = rpcauth_generic_bind_cred,
0df7fb74
TM
1676 .crmatch = gss_match,
1677 .crmarshal = gss_marshal,
1678 .crrefresh = gss_refresh_null,
1679 .crvalidate = gss_validate,
1680 .crwrap_req = gss_wrap_req,
1681 .crunwrap_resp = gss_unwrap_resp,
1682};
1683
b693ba4a 1684static const struct rpc_pipe_ops gss_upcall_ops_v0 = {
c1225158 1685 .upcall = rpc_pipe_generic_upcall,
34769fc4
BF
1686 .downcall = gss_pipe_downcall,
1687 .destroy_msg = gss_pipe_destroy_msg,
1688 .open_pipe = gss_pipe_open_v0,
1689 .release_pipe = gss_pipe_release,
1690};
1691
b693ba4a 1692static const struct rpc_pipe_ops gss_upcall_ops_v1 = {
c1225158 1693 .upcall = rpc_pipe_generic_upcall,
1da177e4
LT
1694 .downcall = gss_pipe_downcall,
1695 .destroy_msg = gss_pipe_destroy_msg,
34769fc4 1696 .open_pipe = gss_pipe_open_v1,
1da177e4
LT
1697 .release_pipe = gss_pipe_release,
1698};
1699
a1db410d
SK
1700static __net_init int rpcsec_gss_init_net(struct net *net)
1701{
1702 return gss_svc_init_net(net);
1703}
1704
1705static __net_exit void rpcsec_gss_exit_net(struct net *net)
1706{
1707 gss_svc_shutdown_net(net);
1708}
1709
1710static struct pernet_operations rpcsec_gss_net_ops = {
1711 .init = rpcsec_gss_init_net,
1712 .exit = rpcsec_gss_exit_net,
1713};
1714
1da177e4
LT
1715/*
1716 * Initialize RPCSEC_GSS module
1717 */
1718static int __init init_rpcsec_gss(void)
1719{
1720 int err = 0;
1721
1722 err = rpcauth_register(&authgss_ops);
1723 if (err)
1724 goto out;
1725 err = gss_svc_init();
1726 if (err)
1727 goto out_unregister;
a1db410d
SK
1728 err = register_pernet_subsys(&rpcsec_gss_net_ops);
1729 if (err)
1730 goto out_svc_exit;
79a3f20b 1731 rpc_init_wait_queue(&pipe_version_rpc_waitqueue, "gss pipe version");
1da177e4 1732 return 0;
a1db410d
SK
1733out_svc_exit:
1734 gss_svc_shutdown();
1da177e4
LT
1735out_unregister:
1736 rpcauth_unregister(&authgss_ops);
1737out:
1738 return err;
1739}
1740
1741static void __exit exit_rpcsec_gss(void)
1742{
a1db410d 1743 unregister_pernet_subsys(&rpcsec_gss_net_ops);
1da177e4
LT
1744 gss_svc_shutdown();
1745 rpcauth_unregister(&authgss_ops);
bf12691d 1746 rcu_barrier(); /* Wait for completion of call_rcu()'s */
1da177e4
LT
1747}
1748
71afa85e 1749MODULE_ALIAS("rpc-auth-6");
1da177e4 1750MODULE_LICENSE("GPL");
126e216a
TM
1751module_param_named(expired_cred_retry_delay,
1752 gss_expired_cred_retry_delay,
1753 uint, 0644);
1754MODULE_PARM_DESC(expired_cred_retry_delay, "Timeout (in seconds) until "
1755 "the RPC engine retries an expired credential");
1756
1da177e4
LT
1757module_init(init_rpcsec_gss)
1758module_exit(exit_rpcsec_gss)
This page took 0.771075 seconds and 5 git commands to generate.