Whamcloud - gitweb
LU-1346 libcfs: replace libcfs wrappers with kernel API
[fs/lustre-release.git] / lustre / ptlrpc / gss / gss_keyring.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  */
30 /*
31  * This file is part of Lustre, http://www.lustre.org/
32  * Lustre is a trademark of Sun Microsystems, Inc.
33  *
34  * lustre/ptlrpc/gss/gss_keyring.c
35  *
36  * Author: Eric Mei <ericm@clusterfs.com>
37  */
38
39 #define DEBUG_SUBSYSTEM S_SEC
40 #ifdef __KERNEL__
41 #include <linux/init.h>
42 #include <linux/module.h>
43 #include <linux/slab.h>
44 #include <linux/dcache.h>
45 #include <linux/fs.h>
46 #include <linux/crypto.h>
47 #include <linux/key.h>
48 #include <linux/keyctl.h>
49 #include <linux/mutex.h>
50 #include <asm/atomic.h>
51 #else
52 #include <liblustre.h>
53 #endif
54
55 #include <obd.h>
56 #include <obd_class.h>
57 #include <obd_support.h>
58 #include <lustre/lustre_idl.h>
59 #include <lustre_sec.h>
60 #include <lustre_net.h>
61 #include <lustre_import.h>
62
63 #include "gss_err.h"
64 #include "gss_internal.h"
65 #include "gss_api.h"
66
67 static struct ptlrpc_sec_policy gss_policy_keyring;
68 static struct ptlrpc_ctx_ops gss_keyring_ctxops;
69 static struct key_type gss_key_type;
70
71 static int sec_install_rctx_kr(struct ptlrpc_sec *sec,
72                                struct ptlrpc_svc_ctx *svc_ctx);
73
74 /*
75  * the timeout is only for the case that upcall child process die abnormally.
76  * in any other cases it should finally update kernel key.
77  * 
78  * FIXME we'd better to incorporate the client & server side upcall timeouts
79  * into the framework of Adaptive Timeouts, but we need to figure out how to
80  * make sure that kernel knows the upcall processes is in-progress or died
81  * unexpectedly.
82  */
83 #define KEYRING_UPCALL_TIMEOUT  (obd_timeout + obd_timeout)
84
85 /****************************************
86  * internal helpers                     *
87  ****************************************/
88
89 #define DUMP_PROCESS_KEYRINGS(tsk)                                      \
90 {                                                                       \
91         CWARN("DUMP PK: %s[%u,%u/%u](<-%s[%u,%u/%u]): "                 \
92               "a %d, t %d, p %d, s %d, u %d, us %d, df %d\n",           \
93               tsk->comm, tsk->pid, tsk->uid, tsk->fsuid,                \
94               tsk->parent->comm, tsk->parent->pid,                      \
95               tsk->parent->uid, tsk->parent->fsuid,                     \
96               tsk->request_key_auth ?                                   \
97               tsk->request_key_auth->serial : 0,                        \
98               tsk->thread_keyring ?                                     \
99               tsk->thread_keyring->serial : 0,                          \
100               tsk->signal->process_keyring ?                            \
101               tsk->signal->process_keyring->serial : 0,                 \
102               tsk->signal->session_keyring ?                            \
103               tsk->signal->session_keyring->serial : 0,                 \
104               tsk->user->uid_keyring ?                                  \
105               tsk->user->uid_keyring->serial : 0,                       \
106               tsk->user->session_keyring ?                              \
107               tsk->user->session_keyring->serial : 0,                   \
108               tsk->jit_keyring                                          \
109              );                                                         \
110 }
111
112 #define DUMP_KEY(key)                                                   \
113 {                                                                       \
114         CWARN("DUMP KEY: %p(%d) ref %d u%u/g%u desc %s\n",              \
115               key, key->serial, atomic_read(&key->usage),               \
116               key->uid, key->gid,                                       \
117               key->description ? key->description : "n/a"               \
118              );                                                         \
119 }
120
121
122 static inline void keyring_upcall_lock(struct gss_sec_keyring *gsec_kr)
123 {
124 #ifdef HAVE_KEYRING_UPCALL_SERIALIZED
125         mutex_lock(&gsec_kr->gsk_uc_lock);
126 #endif
127 }
128
129 static inline void keyring_upcall_unlock(struct gss_sec_keyring *gsec_kr)
130 {
131 #ifdef HAVE_KEYRING_UPCALL_SERIALIZED
132         mutex_unlock(&gsec_kr->gsk_uc_lock);
133 #endif
134 }
135
136 static inline void key_revoke_locked(struct key *key)
137 {
138         set_bit(KEY_FLAG_REVOKED, &key->flags);
139 }
140
141 static void ctx_upcall_timeout_kr(unsigned long data)
142 {
143         struct ptlrpc_cli_ctx *ctx = (struct ptlrpc_cli_ctx *) data;
144         struct key            *key = ctx2gctx_keyring(ctx)->gck_key;
145
146         CWARN("ctx %p, key %p\n", ctx, key);
147
148         LASSERT(key);
149
150         cli_ctx_expire(ctx);
151         key_revoke_locked(key);
152 }
153
154 static
155 void ctx_start_timer_kr(struct ptlrpc_cli_ctx *ctx, long timeout)
156 {
157         struct gss_cli_ctx_keyring *gctx_kr = ctx2gctx_keyring(ctx);
158         struct timer_list          *timer = gctx_kr->gck_timer;
159
160         LASSERT(timer);
161
162         CDEBUG(D_SEC, "ctx %p: start timer %lds\n", ctx, timeout);
163         timeout = timeout * CFS_HZ + cfs_time_current();
164
165         init_timer(timer);
166         timer->expires = timeout;
167         timer->data = (unsigned long ) ctx;
168         timer->function = ctx_upcall_timeout_kr;
169
170         add_timer(timer);
171 }
172
173 /*
174  * caller should make sure no race with other threads
175  */
176 static
177 void ctx_clear_timer_kr(struct ptlrpc_cli_ctx *ctx)
178 {
179         struct gss_cli_ctx_keyring *gctx_kr = ctx2gctx_keyring(ctx);
180         struct timer_list          *timer = gctx_kr->gck_timer;
181
182         if (timer == NULL)
183                 return;
184
185         CDEBUG(D_SEC, "ctx %p, key %p\n", ctx, gctx_kr->gck_key);
186
187         gctx_kr->gck_timer = NULL;
188
189         del_singleshot_timer_sync(timer);
190
191         OBD_FREE_PTR(timer);
192 }
193
194 static
195 struct ptlrpc_cli_ctx *ctx_create_kr(struct ptlrpc_sec *sec,
196                                      struct vfs_cred *vcred)
197 {
198         struct ptlrpc_cli_ctx      *ctx;
199         struct gss_cli_ctx_keyring *gctx_kr;
200
201         OBD_ALLOC_PTR(gctx_kr);
202         if (gctx_kr == NULL)
203                 return NULL;
204
205         OBD_ALLOC_PTR(gctx_kr->gck_timer);
206         if (gctx_kr->gck_timer == NULL) {
207                 OBD_FREE_PTR(gctx_kr);
208                 return NULL;
209         }
210         init_timer(gctx_kr->gck_timer);
211
212         ctx = &gctx_kr->gck_base.gc_base;
213
214         if (gss_cli_ctx_init_common(sec, ctx, &gss_keyring_ctxops, vcred)) {
215                 OBD_FREE_PTR(gctx_kr->gck_timer);
216                 OBD_FREE_PTR(gctx_kr);
217                 return NULL;
218         }
219
220         ctx->cc_expire = cfs_time_current_sec() + KEYRING_UPCALL_TIMEOUT;
221         clear_bit(PTLRPC_CTX_NEW_BIT, &ctx->cc_flags);
222         cfs_atomic_inc(&ctx->cc_refcount); /* for the caller */
223
224         return ctx;
225 }
226
227 static void ctx_destroy_kr(struct ptlrpc_cli_ctx *ctx)
228 {
229         struct ptlrpc_sec          *sec = ctx->cc_sec;
230         struct gss_cli_ctx_keyring *gctx_kr = ctx2gctx_keyring(ctx);
231
232         CDEBUG(D_SEC, "destroying ctx %p\n", ctx);
233
234         /* at this time the association with key has been broken. */
235         LASSERT(sec);
236         LASSERT(cfs_atomic_read(&sec->ps_refcount) > 0);
237         LASSERT(cfs_atomic_read(&sec->ps_nctx) > 0);
238         LASSERT(test_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags) == 0);
239         LASSERT(gctx_kr->gck_key == NULL);
240
241         ctx_clear_timer_kr(ctx);
242         LASSERT(gctx_kr->gck_timer == NULL);
243
244         if (gss_cli_ctx_fini_common(sec, ctx))
245                 return;
246
247         OBD_FREE_PTR(gctx_kr);
248
249         cfs_atomic_dec(&sec->ps_nctx);
250         sptlrpc_sec_put(sec);
251 }
252
253 static void ctx_release_kr(struct ptlrpc_cli_ctx *ctx, int sync)
254 {
255         if (sync) {
256                 ctx_destroy_kr(ctx);
257         } else {
258                 cfs_atomic_inc(&ctx->cc_refcount);
259                 sptlrpc_gc_add_ctx(ctx);
260         }
261 }
262
263 static void ctx_put_kr(struct ptlrpc_cli_ctx *ctx, int sync)
264 {
265         LASSERT(cfs_atomic_read(&ctx->cc_refcount) > 0);
266
267         if (cfs_atomic_dec_and_test(&ctx->cc_refcount))
268                 ctx_release_kr(ctx, sync);
269 }
270
271 /*
272  * key <-> ctx association and rules:
273  * - ctx might not bind with any key
274  * - key/ctx binding is protected by key semaphore (if the key present)
275  * - key and ctx each take a reference of the other
276  * - ctx enlist/unlist is protected by ctx spinlock
277  * - never enlist a ctx after it's been unlisted
278  * - whoever do enlist should also do bind, lock key before enlist:
279  *   - lock key -> lock ctx -> enlist -> unlock ctx -> bind -> unlock key
280  * - whoever do unlist should also do unbind:
281  *   - lock key -> lock ctx -> unlist -> unlock ctx -> unbind -> unlock key
282  *   - lock ctx -> unlist -> unlock ctx -> lock key -> unbind -> unlock key
283  */
284
285 static inline void spin_lock_if(spinlock_t *lock, int condition)
286 {
287         if (condition)
288                 spin_lock(lock);
289 }
290
291 static inline void spin_unlock_if(spinlock_t *lock, int condition)
292 {
293         if (condition)
294                 spin_unlock(lock);
295 }
296
297 static void ctx_enlist_kr(struct ptlrpc_cli_ctx *ctx, int is_root, int locked)
298 {
299         struct ptlrpc_sec      *sec = ctx->cc_sec;
300         struct gss_sec_keyring *gsec_kr = sec2gsec_keyring(sec);
301
302         LASSERT(!test_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags));
303         LASSERT(cfs_atomic_read(&ctx->cc_refcount) > 0);
304
305         spin_lock_if(&sec->ps_lock, !locked);
306
307         cfs_atomic_inc(&ctx->cc_refcount);
308         set_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags);
309         cfs_hlist_add_head(&ctx->cc_cache, &gsec_kr->gsk_clist);
310         if (is_root)
311                 gsec_kr->gsk_root_ctx = ctx;
312
313         spin_unlock_if(&sec->ps_lock, !locked);
314 }
315
316 /*
317  * Note after this get called, caller should not access ctx again because
318  * it might have been freed, unless caller hold at least one refcount of
319  * the ctx.
320  *
321  * return non-zero if we indeed unlist this ctx.
322  */
323 static int ctx_unlist_kr(struct ptlrpc_cli_ctx *ctx, int locked)
324 {
325         struct ptlrpc_sec       *sec = ctx->cc_sec;
326         struct gss_sec_keyring  *gsec_kr = sec2gsec_keyring(sec);
327
328         /* if hashed bit has gone, leave the job to somebody who is doing it */
329         if (test_and_clear_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags) == 0)
330                 return 0;
331
332         /* drop ref inside spin lock to prevent race with other operations */
333         spin_lock_if(&sec->ps_lock, !locked);
334
335         if (gsec_kr->gsk_root_ctx == ctx)
336                 gsec_kr->gsk_root_ctx = NULL;
337         cfs_hlist_del_init(&ctx->cc_cache);
338         cfs_atomic_dec(&ctx->cc_refcount);
339
340         spin_unlock_if(&sec->ps_lock, !locked);
341
342         return 1;
343 }
344
345 /*
346  * bind a key with a ctx together.
347  * caller must hold write lock of the key, as well as ref on key & ctx.
348  */
349 static void bind_key_ctx(struct key *key, struct ptlrpc_cli_ctx *ctx)
350 {
351         LASSERT(cfs_atomic_read(&ctx->cc_refcount) > 0);
352         LASSERT(atomic_read(&key->usage) > 0);
353         LASSERT(ctx2gctx_keyring(ctx)->gck_key == NULL);
354         LASSERT(key->payload.data == NULL);
355
356         /* at this time context may or may not in list. */
357         key_get(key);
358         cfs_atomic_inc(&ctx->cc_refcount);
359         ctx2gctx_keyring(ctx)->gck_key = key;
360         key->payload.data = ctx;
361 }
362
363 /*
364  * unbind a key and a ctx.
365  * caller must hold write lock, as well as a ref of the key.
366  */
367 static void unbind_key_ctx(struct key *key, struct ptlrpc_cli_ctx *ctx)
368 {
369         LASSERT(key->payload.data == ctx);
370         LASSERT(test_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags) == 0);
371
372         /* must revoke the key, or others may treat it as newly created */
373         key_revoke_locked(key);
374
375         key->payload.data = NULL;
376         ctx2gctx_keyring(ctx)->gck_key = NULL;
377
378         /* once ctx get split from key, the timer is meaningless */
379         ctx_clear_timer_kr(ctx);
380
381         ctx_put_kr(ctx, 1);
382         key_put(key);
383 }
384
385 /*
386  * given a ctx, unbind with its coupled key, if any.
387  * unbind could only be called once, so we don't worry the key be released
388  * by someone else.
389  */
390 static void unbind_ctx_kr(struct ptlrpc_cli_ctx *ctx)
391 {
392         struct key      *key = ctx2gctx_keyring(ctx)->gck_key;
393
394         if (key) {
395                 LASSERT(key->payload.data == ctx);
396
397                 key_get(key);
398                 down_write(&key->sem);
399                 unbind_key_ctx(key, ctx);
400                 up_write(&key->sem);
401                 key_put(key);
402         }
403 }
404
405 /*
406  * given a key, unbind with its coupled ctx, if any.
407  * caller must hold write lock, as well as a ref of the key.
408  */
409 static void unbind_key_locked(struct key *key)
410 {
411         struct ptlrpc_cli_ctx   *ctx = key->payload.data;
412
413         if (ctx)
414                 unbind_key_ctx(key, ctx);
415 }
416
417 /*
418  * unlist a ctx, and unbind from coupled key
419  */
420 static void kill_ctx_kr(struct ptlrpc_cli_ctx *ctx)
421 {
422         if (ctx_unlist_kr(ctx, 0))
423                 unbind_ctx_kr(ctx);
424 }
425
426 /*
427  * given a key, unlist and unbind with the coupled ctx (if any).
428  * caller must hold write lock, as well as a ref of the key.
429  */
430 static void kill_key_locked(struct key *key)
431 {
432         struct ptlrpc_cli_ctx *ctx = key->payload.data;
433
434         if (ctx && ctx_unlist_kr(ctx, 0))
435                 unbind_key_locked(key);
436 }
437
438 /*
439  * caller should hold one ref on contexts in freelist.
440  */
441 static void dispose_ctx_list_kr(cfs_hlist_head_t *freelist)
442 {
443         cfs_hlist_node_t       *pos, *next;
444         struct ptlrpc_cli_ctx  *ctx;
445         struct gss_cli_ctx     *gctx;
446
447         cfs_hlist_for_each_entry_safe(ctx, pos, next, freelist, cc_cache) {
448                 cfs_hlist_del_init(&ctx->cc_cache);
449
450                 /* reverse ctx: update current seq to buddy svcctx if exist.
451                  * ideally this should be done at gss_cli_ctx_finalize(), but
452                  * the ctx destroy could be delayed by:
453                  *  1) ctx still has reference;
454                  *  2) ctx destroy is asynchronous;
455                  * and reverse import call inval_all_ctx() require this be done
456                  *_immediately_ otherwise newly created reverse ctx might copy
457                  * the very old sequence number from svcctx. */
458                 gctx = ctx2gctx(ctx);
459                 if (!rawobj_empty(&gctx->gc_svc_handle) &&
460                     sec_is_reverse(gctx->gc_base.cc_sec)) {
461                         gss_svc_upcall_update_sequence(&gctx->gc_svc_handle,
462                                         (__u32) cfs_atomic_read(&gctx->gc_seq));
463                 }
464
465                 /* we need to wakeup waiting reqs here. the context might
466                  * be forced released before upcall finished, then the
467                  * late-arrived downcall can't find the ctx even. */
468                 sptlrpc_cli_ctx_wakeup(ctx);
469
470                 unbind_ctx_kr(ctx);
471                 ctx_put_kr(ctx, 0);
472         }
473 }
474
475 /*
476  * lookup a root context directly in a sec, return root ctx with a
477  * reference taken or NULL.
478  */
479 static
480 struct ptlrpc_cli_ctx * sec_lookup_root_ctx_kr(struct ptlrpc_sec *sec)
481 {
482         struct gss_sec_keyring  *gsec_kr = sec2gsec_keyring(sec);
483         struct ptlrpc_cli_ctx   *ctx = NULL;
484
485         spin_lock(&sec->ps_lock);
486
487         ctx = gsec_kr->gsk_root_ctx;
488
489         if (ctx == NULL && unlikely(sec_is_reverse(sec))) {
490                 cfs_hlist_node_t       *node;
491                 struct ptlrpc_cli_ctx  *tmp;
492
493                 /* reverse ctx, search root ctx in list, choose the one
494                  * with shortest expire time, which is most possibly have
495                  * an established peer ctx at client side. */
496                 cfs_hlist_for_each_entry(tmp, node, &gsec_kr->gsk_clist,
497                                          cc_cache) {
498                         if (ctx == NULL || ctx->cc_expire == 0 ||
499                             ctx->cc_expire > tmp->cc_expire) {
500                                 ctx = tmp;
501                                 /* promote to be root_ctx */
502                                 gsec_kr->gsk_root_ctx = ctx;
503                         }
504                 }
505         }
506
507         if (ctx) {
508                 LASSERT(cfs_atomic_read(&ctx->cc_refcount) > 0);
509                 LASSERT(!cfs_hlist_empty(&gsec_kr->gsk_clist));
510                 cfs_atomic_inc(&ctx->cc_refcount);
511         }
512
513         spin_unlock(&sec->ps_lock);
514
515         return ctx;
516 }
517
518 #define RVS_CTX_EXPIRE_NICE    (10)
519
520 static
521 void rvs_sec_install_root_ctx_kr(struct ptlrpc_sec *sec,
522                                  struct ptlrpc_cli_ctx *new_ctx,
523                                  struct key *key)
524 {
525         struct gss_sec_keyring *gsec_kr = sec2gsec_keyring(sec);
526         cfs_hlist_node_t       *hnode;
527         struct ptlrpc_cli_ctx  *ctx;
528         cfs_time_t              now;
529         ENTRY;
530
531         LASSERT(sec_is_reverse(sec));
532
533         spin_lock(&sec->ps_lock);
534
535         now = cfs_time_current_sec();
536
537         /* set all existing ctxs short expiry */
538         cfs_hlist_for_each_entry(ctx, hnode, &gsec_kr->gsk_clist, cc_cache) {
539                 if (ctx->cc_expire > now + RVS_CTX_EXPIRE_NICE) {
540                         ctx->cc_early_expire = 1;
541                         ctx->cc_expire = now + RVS_CTX_EXPIRE_NICE;
542                 }
543         }
544
545         /* if there's root_ctx there, instead obsolete the current
546          * immediately, we leave it continue operating for a little while.
547          * hopefully when the first backward rpc with newest ctx send out,
548          * the client side already have the peer ctx well established. */
549         ctx_enlist_kr(new_ctx, gsec_kr->gsk_root_ctx ? 0 : 1, 1);
550
551         if (key)
552                 bind_key_ctx(key, new_ctx);
553
554         spin_unlock(&sec->ps_lock);
555 }
556
557 static void construct_key_desc(void *buf, int bufsize,
558                                struct ptlrpc_sec *sec, uid_t uid)
559 {
560         snprintf(buf, bufsize, "%d@%x", uid, sec->ps_id);
561         ((char *)buf)[bufsize - 1] = '\0';
562 }
563
564 /****************************************
565  * sec apis                             *
566  ****************************************/
567
568 static
569 struct ptlrpc_sec * gss_sec_create_kr(struct obd_import *imp,
570                                       struct ptlrpc_svc_ctx *svcctx,
571                                       struct sptlrpc_flavor *sf)
572 {
573         struct gss_sec_keyring  *gsec_kr;
574         ENTRY;
575
576         OBD_ALLOC(gsec_kr, sizeof(*gsec_kr));
577         if (gsec_kr == NULL)
578                 RETURN(NULL);
579
580         CFS_INIT_HLIST_HEAD(&gsec_kr->gsk_clist);
581         gsec_kr->gsk_root_ctx = NULL;
582         mutex_init(&gsec_kr->gsk_root_uc_lock);
583 #ifdef HAVE_KEYRING_UPCALL_SERIALIZED
584         mutex_init(&gsec_kr->gsk_uc_lock);
585 #endif
586
587         if (gss_sec_create_common(&gsec_kr->gsk_base, &gss_policy_keyring,
588                                   imp, svcctx, sf))
589                 goto err_free;
590
591         if (svcctx != NULL &&
592             sec_install_rctx_kr(&gsec_kr->gsk_base.gs_base, svcctx)) {
593                 gss_sec_destroy_common(&gsec_kr->gsk_base);
594                 goto err_free;
595         }
596
597         RETURN(&gsec_kr->gsk_base.gs_base);
598
599 err_free:
600         OBD_FREE(gsec_kr, sizeof(*gsec_kr));
601         RETURN(NULL);
602 }
603
604 static
605 void gss_sec_destroy_kr(struct ptlrpc_sec *sec)
606 {
607         struct gss_sec          *gsec = sec2gsec(sec);
608         struct gss_sec_keyring  *gsec_kr = sec2gsec_keyring(sec);
609
610         CDEBUG(D_SEC, "destroy %s@%p\n", sec->ps_policy->sp_name, sec);
611
612         LASSERT(cfs_hlist_empty(&gsec_kr->gsk_clist));
613         LASSERT(gsec_kr->gsk_root_ctx == NULL);
614
615         gss_sec_destroy_common(gsec);
616
617         OBD_FREE(gsec_kr, sizeof(*gsec_kr));
618 }
619
620 static inline int user_is_root(struct ptlrpc_sec *sec, struct vfs_cred *vcred)
621 {
622         /* except the ROOTONLY flag, treat it as root user only if real uid
623          * is 0, euid/fsuid being 0 are handled as setuid scenarios */
624         if (sec_is_rootonly(sec) || (vcred->vc_uid == 0))
625                 return 1;
626         else
627                 return 0;
628 }
629
630 /*
631  * unlink request key from it's ring, which is linked during request_key().
632  * sadly, we have to 'guess' which keyring it's linked to.
633  *
634  * FIXME this code is fragile, depend on how request_key_link() is implemented.
635  */
636 static void request_key_unlink(struct key *key)
637 {
638         struct task_struct *tsk = current;
639         struct key *ring;
640
641         switch (tsk->jit_keyring) {
642         case KEY_REQKEY_DEFL_DEFAULT:
643         case KEY_REQKEY_DEFL_THREAD_KEYRING:
644                 ring = key_get(tsk->thread_keyring);
645                 if (ring)
646                         break;
647         case KEY_REQKEY_DEFL_PROCESS_KEYRING:
648                 ring = key_get(tsk->signal->process_keyring);
649                 if (ring)
650                         break;
651         case KEY_REQKEY_DEFL_SESSION_KEYRING:
652                 rcu_read_lock();
653                 ring = key_get(rcu_dereference(tsk->signal->session_keyring));
654                 rcu_read_unlock();
655                 if (ring)
656                         break;
657         case KEY_REQKEY_DEFL_USER_SESSION_KEYRING:
658                 ring = key_get(tsk->user->session_keyring);
659                 break;
660         case KEY_REQKEY_DEFL_USER_KEYRING:
661                 ring = key_get(tsk->user->uid_keyring);
662                 break;
663         case KEY_REQKEY_DEFL_GROUP_KEYRING:
664         default:
665                 LBUG();
666         }
667
668         LASSERT(ring);
669         key_unlink(ring, key);
670         key_put(ring);
671 }
672
673 static
674 struct ptlrpc_cli_ctx * gss_sec_lookup_ctx_kr(struct ptlrpc_sec *sec,
675                                               struct vfs_cred *vcred,
676                                               int create, int remove_dead)
677 {
678         struct obd_import       *imp = sec->ps_import;
679         struct gss_sec_keyring  *gsec_kr = sec2gsec_keyring(sec);
680         struct ptlrpc_cli_ctx   *ctx = NULL;
681         unsigned int             is_root = 0, create_new = 0;
682         struct key              *key;
683         char                     desc[24];
684         char                    *coinfo;
685         int                      coinfo_size;
686         char                    *co_flags = "";
687         ENTRY;
688
689         LASSERT(imp != NULL);
690
691         is_root = user_is_root(sec, vcred);
692
693         /* a little bit optimization for root context */
694         if (is_root) {
695                 ctx = sec_lookup_root_ctx_kr(sec);
696                 /*
697                  * Only lookup directly for REVERSE sec, which should
698                  * always succeed.
699                  */
700                 if (ctx || sec_is_reverse(sec))
701                         RETURN(ctx);
702         }
703
704         LASSERT(create != 0);
705
706         /* for root context, obtain lock and check again, this time hold
707          * the root upcall lock, make sure nobody else populated new root
708          * context after last check. */
709         if (is_root) {
710                 mutex_lock(&gsec_kr->gsk_root_uc_lock);
711
712                 ctx = sec_lookup_root_ctx_kr(sec);
713                 if (ctx)
714                         goto out;
715
716                 /* update reverse handle for root user */
717                 sec2gsec(sec)->gs_rvs_hdl = gss_get_next_ctx_index();
718
719                 switch (sec->ps_part) {
720                 case LUSTRE_SP_MDT:
721                         co_flags = "m";
722                         break;
723                 case LUSTRE_SP_OST:
724                         co_flags = "o";
725                         break;
726                 case LUSTRE_SP_MGC:
727                         co_flags = "rmo";
728                         break;
729                 case LUSTRE_SP_CLI:
730                         co_flags = "r";
731                         break;
732                 case LUSTRE_SP_MGS:
733                 default:
734                         LBUG();
735                 }
736         }
737
738         /* in case of setuid, key will be constructed as owner of fsuid/fsgid,
739          * but we do authentication based on real uid/gid. the key permission
740          * bits will be exactly as POS_ALL, so only processes who subscribed
741          * this key could have the access, although the quota might be counted
742          * on others (fsuid/fsgid).
743          *
744          * keyring will use fsuid/fsgid as upcall parameters, so we have to
745          * encode real uid/gid into callout info.
746          */
747
748         construct_key_desc(desc, sizeof(desc), sec, vcred->vc_uid);
749
750         /* callout info format:
751          * secid:mech:uid:gid:flags:svc_type:peer_nid:target_uuid
752          */
753         coinfo_size = sizeof(struct obd_uuid) + MAX_OBD_NAME + 64;
754         OBD_ALLOC(coinfo, coinfo_size);
755         if (coinfo == NULL)
756                 goto out;
757
758         snprintf(coinfo, coinfo_size, "%d:%s:%u:%u:%s:%d:"LPX64":%s",
759                  sec->ps_id, sec2gsec(sec)->gs_mech->gm_name,
760                  vcred->vc_uid, vcred->vc_gid,
761                  co_flags, import_to_gss_svc(imp),
762                  imp->imp_connection->c_peer.nid, imp->imp_obd->obd_name);
763
764         CDEBUG(D_SEC, "requesting key for %s\n", desc);
765
766         keyring_upcall_lock(gsec_kr);
767         key = request_key(&gss_key_type, desc, coinfo);
768         keyring_upcall_unlock(gsec_kr);
769
770         OBD_FREE(coinfo, coinfo_size);
771
772         if (IS_ERR(key)) {
773                 CERROR("failed request key: %ld\n", PTR_ERR(key));
774                 goto out;
775         }
776         CDEBUG(D_SEC, "obtained key %08x for %s\n", key->serial, desc);
777
778         /* once payload.data was pointed to a ctx, it never changes until
779          * we de-associate them; but parallel request_key() may return
780          * a key with payload.data == NULL at the same time. so we still
781          * need wirtelock of key->sem to serialize them. */
782         down_write(&key->sem);
783
784         if (likely(key->payload.data != NULL)) {
785                 ctx = key->payload.data;
786
787                 LASSERT(cfs_atomic_read(&ctx->cc_refcount) >= 1);
788                 LASSERT(ctx2gctx_keyring(ctx)->gck_key == key);
789                 LASSERT(atomic_read(&key->usage) >= 2);
790
791                 /* simply take a ref and return. it's upper layer's
792                  * responsibility to detect & replace dead ctx. */
793                 cfs_atomic_inc(&ctx->cc_refcount);
794         } else {
795                 /* pre initialization with a cli_ctx. this can't be done in
796                  * key_instantiate() because we'v no enough information
797                  * there. */
798                 ctx = ctx_create_kr(sec, vcred);
799                 if (ctx != NULL) {
800                         ctx_enlist_kr(ctx, is_root, 0);
801                         bind_key_ctx(key, ctx);
802
803                         ctx_start_timer_kr(ctx, KEYRING_UPCALL_TIMEOUT);
804
805                         CDEBUG(D_SEC, "installed key %p <-> ctx %p (sec %p)\n",
806                                key, ctx, sec);
807                 } else {
808                         /* we'd prefer to call key_revoke(), but we more like
809                          * to revoke it within this key->sem locked period. */
810                         key_revoke_locked(key);
811                 }
812
813                 create_new = 1;
814         }
815
816         up_write(&key->sem);
817
818         if (is_root && create_new)
819                 request_key_unlink(key);
820
821         key_put(key);
822 out:
823         if (is_root)
824                 mutex_unlock(&gsec_kr->gsk_root_uc_lock);
825         RETURN(ctx);
826 }
827
828 static
829 void gss_sec_release_ctx_kr(struct ptlrpc_sec *sec,
830                             struct ptlrpc_cli_ctx *ctx,
831                             int sync)
832 {
833         LASSERT(cfs_atomic_read(&sec->ps_refcount) > 0);
834         LASSERT(cfs_atomic_read(&ctx->cc_refcount) == 0);
835         ctx_release_kr(ctx, sync);
836 }
837
838 /*
839  * flush context of normal user, we must resort to keyring itself to find out
840  * contexts which belong to me.
841  *
842  * Note here we suppose only to flush _my_ context, the "uid" will
843  * be ignored in the search.
844  */
845 static
846 void flush_user_ctx_cache_kr(struct ptlrpc_sec *sec,
847                              uid_t uid,
848                              int grace, int force)
849 {
850         struct key              *key;
851         char                     desc[24];
852
853         /* nothing to do for reverse or rootonly sec */
854         if (sec_is_reverse(sec) || sec_is_rootonly(sec))
855                 return;
856
857         construct_key_desc(desc, sizeof(desc), sec, uid);
858
859         /* there should be only one valid key, but we put it in the
860          * loop in case of any weird cases */
861         for (;;) {
862                 key = request_key(&gss_key_type, desc, NULL);
863                 if (IS_ERR(key)) {
864                         CDEBUG(D_SEC, "No more key found for current user\n");
865                         break;
866                 }
867
868                 down_write(&key->sem);
869
870                 kill_key_locked(key);
871
872                 /* kill_key_locked() should usually revoke the key, but we
873                  * revoke it again to make sure, e.g. some case the key may
874                  * not well coupled with a context. */
875                 key_revoke_locked(key);
876
877                 up_write(&key->sem);
878
879                 key_put(key);
880         }
881 }
882
883 /*
884  * flush context of root or all, we iterate through the list.
885  */
886 static
887 void flush_spec_ctx_cache_kr(struct ptlrpc_sec *sec,
888                              uid_t uid,
889                              int grace, int force)
890 {
891         struct gss_sec_keyring *gsec_kr;
892         cfs_hlist_head_t        freelist = CFS_HLIST_HEAD_INIT;
893         cfs_hlist_node_t       *pos, *next;
894         struct ptlrpc_cli_ctx  *ctx;
895         ENTRY;
896
897         gsec_kr = sec2gsec_keyring(sec);
898
899         spin_lock(&sec->ps_lock);
900         cfs_hlist_for_each_entry_safe(ctx, pos, next,
901                                       &gsec_kr->gsk_clist, cc_cache) {
902                 LASSERT(cfs_atomic_read(&ctx->cc_refcount) > 0);
903
904                 if (uid != -1 && uid != ctx->cc_vcred.vc_uid)
905                         continue;
906
907                 /* at this moment there's at least 2 base reference:
908                  * key association and in-list. */
909                 if (cfs_atomic_read(&ctx->cc_refcount) > 2) {
910                         if (!force)
911                                 continue;
912                         CWARN("flush busy ctx %p(%u->%s, extra ref %d)\n",
913                               ctx, ctx->cc_vcred.vc_uid,
914                               sec2target_str(ctx->cc_sec),
915                               cfs_atomic_read(&ctx->cc_refcount) - 2);
916                 }
917
918                 set_bit(PTLRPC_CTX_DEAD_BIT, &ctx->cc_flags);
919                 if (!grace)
920                         clear_bit(PTLRPC_CTX_UPTODATE_BIT, &ctx->cc_flags);
921
922                 cfs_atomic_inc(&ctx->cc_refcount);
923
924                 if (ctx_unlist_kr(ctx, 1)) {
925                         cfs_hlist_add_head(&ctx->cc_cache, &freelist);
926                 } else {
927                         LASSERT(cfs_atomic_read(&ctx->cc_refcount) >= 2);
928                         cfs_atomic_dec(&ctx->cc_refcount);
929                 }
930         }
931         spin_unlock(&sec->ps_lock);
932
933         dispose_ctx_list_kr(&freelist);
934         EXIT;
935 }
936
937 static
938 int gss_sec_flush_ctx_cache_kr(struct ptlrpc_sec *sec,
939                                uid_t uid, int grace, int force)
940 {
941         ENTRY;
942
943         CDEBUG(D_SEC, "sec %p(%d, nctx %d), uid %d, grace %d, force %d\n",
944                sec, cfs_atomic_read(&sec->ps_refcount),
945                cfs_atomic_read(&sec->ps_nctx),
946                uid, grace, force);
947
948         if (uid != -1 && uid != 0)
949                 flush_user_ctx_cache_kr(sec, uid, grace, force);
950         else
951                 flush_spec_ctx_cache_kr(sec, uid, grace, force);
952
953         RETURN(0);
954 }
955
956 static
957 void gss_sec_gc_ctx_kr(struct ptlrpc_sec *sec)
958 {
959         struct gss_sec_keyring *gsec_kr = sec2gsec_keyring(sec);
960         cfs_hlist_head_t        freelist = CFS_HLIST_HEAD_INIT;
961         cfs_hlist_node_t       *pos, *next;
962         struct ptlrpc_cli_ctx  *ctx;
963         ENTRY;
964
965         CWARN("running gc\n");
966
967         spin_lock(&sec->ps_lock);
968         cfs_hlist_for_each_entry_safe(ctx, pos, next,
969                                       &gsec_kr->gsk_clist, cc_cache) {
970                 LASSERT(cfs_atomic_read(&ctx->cc_refcount) > 0);
971
972                 cfs_atomic_inc(&ctx->cc_refcount);
973
974                 if (cli_ctx_check_death(ctx) && ctx_unlist_kr(ctx, 1)) {
975                         cfs_hlist_add_head(&ctx->cc_cache, &freelist);
976                         CWARN("unhashed ctx %p\n", ctx);
977                 } else {
978                         LASSERT(cfs_atomic_read(&ctx->cc_refcount) >= 2);
979                         cfs_atomic_dec(&ctx->cc_refcount);
980                 }
981         }
982         spin_unlock(&sec->ps_lock);
983
984         dispose_ctx_list_kr(&freelist);
985         EXIT;
986         return;
987 }
988
989 static
990 int gss_sec_display_kr(struct ptlrpc_sec *sec, struct seq_file *seq)
991 {
992         struct gss_sec_keyring *gsec_kr = sec2gsec_keyring(sec);
993         cfs_hlist_node_t       *pos, *next;
994         struct ptlrpc_cli_ctx  *ctx;
995         struct gss_cli_ctx     *gctx;
996         time_t                  now = cfs_time_current_sec();
997         ENTRY;
998
999         spin_lock(&sec->ps_lock);
1000         cfs_hlist_for_each_entry_safe(ctx, pos, next,
1001                                   &gsec_kr->gsk_clist, cc_cache) {
1002                 struct key             *key;
1003                 char                    flags_str[40];
1004                 char                    mech[40];
1005
1006                 gctx = ctx2gctx(ctx);
1007                 key = ctx2gctx_keyring(ctx)->gck_key;
1008
1009                 gss_cli_ctx_flags2str(ctx->cc_flags,
1010                                       flags_str, sizeof(flags_str));
1011
1012                 if (gctx->gc_mechctx)
1013                         lgss_display(gctx->gc_mechctx, mech, sizeof(mech));
1014                 else
1015                         snprintf(mech, sizeof(mech), "N/A");
1016                 mech[sizeof(mech) - 1] = '\0';
1017
1018                 seq_printf(seq, "%p: uid %u, ref %d, expire %ld(%+ld), fl %s, "
1019                            "seq %d, win %u, key %08x(ref %d), "
1020                            "hdl "LPX64":"LPX64", mech: %s\n",
1021                            ctx, ctx->cc_vcred.vc_uid,
1022                            cfs_atomic_read(&ctx->cc_refcount),
1023                            ctx->cc_expire,
1024                            ctx->cc_expire ?  ctx->cc_expire - now : 0,
1025                            flags_str,
1026                            cfs_atomic_read(&gctx->gc_seq),
1027                            gctx->gc_win,
1028                            key ? key->serial : 0,
1029                            key ? atomic_read(&key->usage) : 0,
1030                            gss_handle_to_u64(&gctx->gc_handle),
1031                            gss_handle_to_u64(&gctx->gc_svc_handle),
1032                            mech);
1033         }
1034         spin_unlock(&sec->ps_lock);
1035
1036         RETURN(0);
1037 }
1038
1039 /****************************************
1040  * cli_ctx apis                         *
1041  ****************************************/
1042
1043 static
1044 int gss_cli_ctx_refresh_kr(struct ptlrpc_cli_ctx *ctx)
1045 {
1046         /* upcall is already on the way */
1047         return 0;
1048 }
1049
1050 static
1051 int gss_cli_ctx_validate_kr(struct ptlrpc_cli_ctx *ctx)
1052 {
1053         LASSERT(cfs_atomic_read(&ctx->cc_refcount) > 0);
1054         LASSERT(ctx->cc_sec);
1055
1056         if (cli_ctx_check_death(ctx)) {
1057                 kill_ctx_kr(ctx);
1058                 return 1;
1059         }
1060
1061         if (cli_ctx_is_ready(ctx))
1062                 return 0;
1063         return 1;
1064 }
1065
1066 static
1067 void gss_cli_ctx_die_kr(struct ptlrpc_cli_ctx *ctx, int grace)
1068 {
1069         LASSERT(cfs_atomic_read(&ctx->cc_refcount) > 0);
1070         LASSERT(ctx->cc_sec);
1071
1072         cli_ctx_expire(ctx);
1073         kill_ctx_kr(ctx);
1074 }
1075
1076 /****************************************
1077  * (reverse) service                    *
1078  ****************************************/
1079
1080 /*
1081  * reverse context could have nothing to do with keyrings. here we still keep
1082  * the version which bind to a key, for future reference.
1083  */
1084 #define HAVE_REVERSE_CTX_NOKEY
1085
1086 #ifdef HAVE_REVERSE_CTX_NOKEY
1087
1088 static
1089 int sec_install_rctx_kr(struct ptlrpc_sec *sec,
1090                         struct ptlrpc_svc_ctx *svc_ctx)
1091 {
1092         struct ptlrpc_cli_ctx   *cli_ctx;
1093         struct vfs_cred          vcred = { 0, 0 };
1094         int                      rc;
1095
1096         LASSERT(sec);
1097         LASSERT(svc_ctx);
1098
1099         cli_ctx = ctx_create_kr(sec, &vcred);
1100         if (cli_ctx == NULL)
1101                 return -ENOMEM;
1102
1103         rc = gss_copy_rvc_cli_ctx(cli_ctx, svc_ctx);
1104         if (rc) {
1105                 CERROR("failed copy reverse cli ctx: %d\n", rc);
1106
1107                 ctx_put_kr(cli_ctx, 1);
1108                 return rc;
1109         }
1110
1111         rvs_sec_install_root_ctx_kr(sec, cli_ctx, NULL);
1112
1113         ctx_put_kr(cli_ctx, 1);
1114
1115         return 0;
1116 }
1117
1118 #else /* ! HAVE_REVERSE_CTX_NOKEY */
1119
1120 static
1121 int sec_install_rctx_kr(struct ptlrpc_sec *sec,
1122                         struct ptlrpc_svc_ctx *svc_ctx)
1123 {
1124         struct ptlrpc_cli_ctx   *cli_ctx = NULL;
1125         struct key              *key;
1126         struct vfs_cred          vcred = { 0, 0 };
1127         char                     desc[64];
1128         int                      rc;
1129
1130         LASSERT(sec);
1131         LASSERT(svc_ctx);
1132         CWARN("called\n");
1133
1134         construct_key_desc(desc, sizeof(desc), sec, 0);
1135
1136         key = key_alloc(&gss_key_type, desc, 0, 0,
1137                         KEY_POS_ALL | KEY_USR_ALL, 1);
1138         if (IS_ERR(key)) {
1139                 CERROR("failed to alloc key: %ld\n", PTR_ERR(key));
1140                 return PTR_ERR(key);
1141         }
1142
1143         rc = key_instantiate_and_link(key, NULL, 0, NULL, NULL);
1144         if (rc) {
1145                 CERROR("failed to instantiate key: %d\n", rc);
1146                 goto err_revoke;
1147         }
1148
1149         down_write(&key->sem);
1150
1151         LASSERT(key->payload.data == NULL);
1152
1153         cli_ctx = ctx_create_kr(sec, &vcred);
1154         if (cli_ctx == NULL) {
1155                 rc = -ENOMEM;
1156                 goto err_up;
1157         }
1158
1159         rc = gss_copy_rvc_cli_ctx(cli_ctx, svc_ctx);
1160         if (rc) {
1161                 CERROR("failed copy reverse cli ctx: %d\n", rc);
1162                 goto err_put;
1163         }
1164
1165         rvs_sec_install_root_ctx_kr(sec, cli_ctx, key);
1166
1167         ctx_put_kr(cli_ctx, 1);
1168         up_write(&key->sem);
1169
1170         rc = 0;
1171         CWARN("ok!\n");
1172 out:
1173         key_put(key);
1174         return rc;
1175
1176 err_put:
1177         ctx_put_kr(cli_ctx, 1);
1178 err_up:
1179         up_write(&key->sem);
1180 err_revoke:
1181         key_revoke(key);
1182         goto out;
1183 }
1184
1185 #endif /* HAVE_REVERSE_CTX_NOKEY */
1186
1187 /****************************************
1188  * service apis                         *
1189  ****************************************/
1190
1191 static
1192 int gss_svc_accept_kr(struct ptlrpc_request *req)
1193 {
1194         return gss_svc_accept(&gss_policy_keyring, req);
1195 }
1196
1197 static
1198 int gss_svc_install_rctx_kr(struct obd_import *imp,
1199                             struct ptlrpc_svc_ctx *svc_ctx)
1200 {
1201         struct ptlrpc_sec *sec;
1202         int                rc;
1203
1204         sec = sptlrpc_import_sec_ref(imp);
1205         LASSERT(sec);
1206
1207         rc = sec_install_rctx_kr(sec, svc_ctx);
1208         sptlrpc_sec_put(sec);
1209
1210         return rc;
1211 }
1212
1213 /****************************************
1214  * key apis                             *
1215  ****************************************/
1216
1217 static
1218 int gss_kt_instantiate(struct key *key, const void *data, size_t datalen)
1219 {
1220         int             rc;
1221         ENTRY;
1222
1223         if (data != NULL || datalen != 0) {
1224                 CERROR("invalid: data %p, len %lu\n", data, (long)datalen);
1225                 RETURN(-EINVAL);
1226         }
1227
1228         if (key->payload.data != 0) {
1229                 CERROR("key already have payload\n");
1230                 RETURN(-EINVAL);
1231         }
1232
1233         /* link the key to session keyring, so following context negotiation
1234          * rpc fired from user space could find this key. This will be unlinked
1235          * automatically when upcall processes die.
1236          *
1237          * we can't do this through keyctl from userspace, because the upcall
1238          * might be neither possessor nor owner of the key (setuid).
1239          *
1240          * the session keyring is created upon upcall, and don't change all
1241          * the way until upcall finished, so rcu lock is not needed here.
1242          */
1243         LASSERT(cfs_current()->signal->session_keyring);
1244
1245         lockdep_off();
1246         rc = key_link(cfs_current()->signal->session_keyring, key);
1247         lockdep_on();
1248         if (unlikely(rc)) {
1249                 CERROR("failed to link key %08x to keyring %08x: %d\n",
1250                        key->serial,
1251                        cfs_current()->signal->session_keyring->serial, rc);
1252                 RETURN(rc);
1253         }
1254
1255         CDEBUG(D_SEC, "key %p instantiated, ctx %p\n", key, key->payload.data);
1256         RETURN(0);
1257 }
1258
1259 /*
1260  * called with key semaphore write locked. it means we can operate
1261  * on the context without fear of loosing refcount.
1262  */
1263 static
1264 int gss_kt_update(struct key *key, const void *data, size_t datalen)
1265 {
1266         struct ptlrpc_cli_ctx   *ctx = key->payload.data;
1267         struct gss_cli_ctx      *gctx;
1268         rawobj_t                 tmpobj = RAWOBJ_EMPTY;
1269         __u32                    datalen32 = (__u32) datalen;
1270         int                      rc;
1271         ENTRY;
1272
1273         if (data == NULL || datalen == 0) {
1274                 CWARN("invalid: data %p, len %lu\n", data, (long)datalen);
1275                 RETURN(-EINVAL);
1276         }
1277
1278         /* if upcall finished negotiation too fast (mostly likely because
1279          * of local error happened) and call kt_update(), the ctx
1280          * might be still NULL. but the key will finally be associate
1281          * with a context, or be revoked. if key status is fine, return
1282          * -EAGAIN to allow userspace sleep a while and call again. */
1283         if (ctx == NULL) {
1284                 CDEBUG(D_SEC, "update too soon: key %p(%x) flags %lx\n",
1285                       key, key->serial, key->flags);
1286
1287                 rc = key_validate(key);
1288                 if (rc == 0)
1289                         RETURN(-EAGAIN);
1290                 else
1291                         RETURN(rc);
1292         }
1293
1294         LASSERT(cfs_atomic_read(&ctx->cc_refcount) > 0);
1295         LASSERT(ctx->cc_sec);
1296
1297         ctx_clear_timer_kr(ctx);
1298
1299         /* don't proceed if already refreshed */
1300         if (cli_ctx_is_refreshed(ctx)) {
1301                 CWARN("ctx already done refresh\n");
1302                 RETURN(0);
1303         }
1304
1305         sptlrpc_cli_ctx_get(ctx);
1306         gctx = ctx2gctx(ctx);
1307
1308         rc = buffer_extract_bytes(&data, &datalen32, &gctx->gc_win,
1309                                   sizeof(gctx->gc_win));
1310         if (rc) {
1311                 CERROR("failed extract seq_win\n");
1312                 goto out;
1313         }
1314
1315         if (gctx->gc_win == 0) {
1316                 __u32   nego_rpc_err, nego_gss_err;
1317
1318                 rc = buffer_extract_bytes(&data, &datalen32, &nego_rpc_err,
1319                                           sizeof(nego_rpc_err));
1320                 if (rc) {
1321                         CERROR("failed to extrace rpc rc\n");
1322                         goto out;
1323                 }
1324
1325                 rc = buffer_extract_bytes(&data, &datalen32, &nego_gss_err,
1326                                           sizeof(nego_gss_err));
1327                 if (rc) {
1328                         CERROR("failed to extrace gss rc\n");
1329                         goto out;
1330                 }
1331
1332                 CERROR("negotiation: rpc err %d, gss err %x\n",
1333                        nego_rpc_err, nego_gss_err);
1334
1335                 rc = nego_rpc_err ? nego_rpc_err : -EACCES;
1336         } else {
1337                 rc = rawobj_extract_local_alloc(&gctx->gc_handle,
1338                                                 (__u32 **) &data, &datalen32);
1339                 if (rc) {
1340                         CERROR("failed extract handle\n");
1341                         goto out;
1342                 }
1343
1344                 rc = rawobj_extract_local(&tmpobj, (__u32 **) &data,&datalen32);
1345                 if (rc) {
1346                         CERROR("failed extract mech\n");
1347                         goto out;
1348                 }
1349
1350                 rc = lgss_import_sec_context(&tmpobj,
1351                                              sec2gsec(ctx->cc_sec)->gs_mech,
1352                                              &gctx->gc_mechctx);
1353                 if (rc != GSS_S_COMPLETE)
1354                         CERROR("failed import context\n");
1355                 else
1356                         rc = 0;
1357         }
1358 out:
1359         /* we don't care what current status of this ctx, even someone else
1360          * is operating on the ctx at the same time. we just add up our own
1361          * opinions here. */
1362         if (rc == 0) {
1363                 gss_cli_ctx_uptodate(gctx);
1364         } else {
1365                 /* this will also revoke the key. has to be done before
1366                  * wakeup waiters otherwise they can find the stale key */
1367                 kill_key_locked(key);
1368
1369                 cli_ctx_expire(ctx);
1370
1371                 if (rc != -ERESTART)
1372                         set_bit(PTLRPC_CTX_ERROR_BIT, &ctx->cc_flags);
1373         }
1374
1375         /* let user space think it's a success */
1376         sptlrpc_cli_ctx_put(ctx, 1);
1377         RETURN(0);
1378 }
1379
1380 static
1381 int gss_kt_match(const struct key *key, const void *desc)
1382 {
1383         return (strcmp(key->description, (const char *) desc) == 0);
1384 }
1385
1386 static
1387 void gss_kt_destroy(struct key *key)
1388 {
1389         ENTRY;
1390         LASSERT(key->payload.data == NULL);
1391         CDEBUG(D_SEC, "destroy key %p\n", key);
1392         EXIT;
1393 }
1394
1395 static
1396 void gss_kt_describe(const struct key *key, struct seq_file *s)
1397 {
1398         if (key->description == NULL)
1399                 seq_puts(s, "[null]");
1400         else
1401                 seq_puts(s, key->description);
1402 }
1403
1404 static struct key_type gss_key_type =
1405 {
1406         .name           = "lgssc",
1407         .def_datalen    = 0,
1408         .instantiate    = gss_kt_instantiate,
1409         .update         = gss_kt_update,
1410         .match          = gss_kt_match,
1411         .destroy        = gss_kt_destroy,
1412         .describe       = gss_kt_describe,
1413 };
1414
1415 /****************************************
1416  * lustre gss keyring policy            *
1417  ****************************************/
1418
1419 static struct ptlrpc_ctx_ops gss_keyring_ctxops = {
1420         .match                  = gss_cli_ctx_match,
1421         .refresh                = gss_cli_ctx_refresh_kr,
1422         .validate               = gss_cli_ctx_validate_kr,
1423         .die                    = gss_cli_ctx_die_kr,
1424         .sign                   = gss_cli_ctx_sign,
1425         .verify                 = gss_cli_ctx_verify,
1426         .seal                   = gss_cli_ctx_seal,
1427         .unseal                 = gss_cli_ctx_unseal,
1428         .wrap_bulk              = gss_cli_ctx_wrap_bulk,
1429         .unwrap_bulk            = gss_cli_ctx_unwrap_bulk,
1430 };
1431
1432 static struct ptlrpc_sec_cops gss_sec_keyring_cops = {
1433         .create_sec             = gss_sec_create_kr,
1434         .destroy_sec            = gss_sec_destroy_kr,
1435         .kill_sec               = gss_sec_kill,
1436         .lookup_ctx             = gss_sec_lookup_ctx_kr,
1437         .release_ctx            = gss_sec_release_ctx_kr,
1438         .flush_ctx_cache        = gss_sec_flush_ctx_cache_kr,
1439         .gc_ctx                 = gss_sec_gc_ctx_kr,
1440         .install_rctx           = gss_sec_install_rctx,
1441         .alloc_reqbuf           = gss_alloc_reqbuf,
1442         .free_reqbuf            = gss_free_reqbuf,
1443         .alloc_repbuf           = gss_alloc_repbuf,
1444         .free_repbuf            = gss_free_repbuf,
1445         .enlarge_reqbuf         = gss_enlarge_reqbuf,
1446         .display                = gss_sec_display_kr,
1447 };
1448
1449 static struct ptlrpc_sec_sops gss_sec_keyring_sops = {
1450         .accept                 = gss_svc_accept_kr,
1451         .invalidate_ctx         = gss_svc_invalidate_ctx,
1452         .alloc_rs               = gss_svc_alloc_rs,
1453         .authorize              = gss_svc_authorize,
1454         .free_rs                = gss_svc_free_rs,
1455         .free_ctx               = gss_svc_free_ctx,
1456         .prep_bulk              = gss_svc_prep_bulk,
1457         .unwrap_bulk            = gss_svc_unwrap_bulk,
1458         .wrap_bulk              = gss_svc_wrap_bulk,
1459         .install_rctx           = gss_svc_install_rctx_kr,
1460 };
1461
1462 static struct ptlrpc_sec_policy gss_policy_keyring = {
1463         .sp_owner               = THIS_MODULE,
1464         .sp_name                = "gss.keyring",
1465         .sp_policy              = SPTLRPC_POLICY_GSS,
1466         .sp_cops                = &gss_sec_keyring_cops,
1467         .sp_sops                = &gss_sec_keyring_sops,
1468 };
1469
1470
1471 int __init gss_init_keyring(void)
1472 {
1473         int rc;
1474
1475         rc = register_key_type(&gss_key_type);
1476         if (rc) {
1477                 CERROR("failed to register keyring type: %d\n", rc);
1478                 return rc;
1479         }
1480
1481         rc = sptlrpc_register_policy(&gss_policy_keyring);
1482         if (rc) {
1483                 unregister_key_type(&gss_key_type);
1484                 return rc;
1485         }
1486
1487         return 0;
1488 }
1489
1490 void __exit gss_exit_keyring(void)
1491 {
1492         unregister_key_type(&gss_key_type);
1493         sptlrpc_unregister_policy(&gss_policy_keyring);
1494 }