Whamcloud - gitweb
LU-4423 ptlrpc: use 64-bit times for ptlrpc_sec
[fs/lustre-release.git] / lustre / ptlrpc / gss / gss_pipefs.c
1 /*
2  * Modifications for Lustre
3  *
4  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
5  *
6  * Copyright (c) 2012, 2016, Intel Corporation.
7  *
8  * Author: Eric Mei <ericm@clusterfs.com>
9  */
10
11 /*
12  * linux/net/sunrpc/auth_gss.c
13  *
14  * RPCSEC_GSS client authentication.
15  *
16  *  Copyright (c) 2000 The Regents of the University of Michigan.
17  *  All rights reserved.
18  *
19  *  Dug Song       <dugsong@monkey.org>
20  *  Andy Adamson   <andros@umich.edu>
21  *
22  *  Redistribution and use in source and binary forms, with or without
23  *  modification, are permitted provided that the following conditions
24  *  are met:
25  *
26  *  1. Redistributions of source code must retain the above copyright
27  *     notice, this list of conditions and the following disclaimer.
28  *  2. Redistributions in binary form must reproduce the above copyright
29  *     notice, this list of conditions and the following disclaimer in the
30  *     documentation and/or other materials provided with the distribution.
31  *  3. Neither the name of the University nor the names of its
32  *     contributors may be used to endorse or promote products derived
33  *     from this software without specific prior written permission.
34  *
35  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
36  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
37  *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38  *  DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
39  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
40  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
41  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
42  *  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
43  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
44  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
45  *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46  *
47  */
48
49 #define DEBUG_SUBSYSTEM S_SEC
50 #include <linux/init.h>
51 #include <linux/module.h>
52 #include <linux/slab.h>
53 #include <linux/dcache.h>
54 #include <linux/fs.h>
55 #include <linux/mutex.h>
56 #include <linux/crypto.h>
57 #include <asm/atomic.h>
58 struct rpc_clnt; /* for rpc_pipefs */
59 #include <linux/sunrpc/rpc_pipe_fs.h>
60
61 #include <libcfs/linux/linux-list.h>
62 #include <obd.h>
63 #include <obd_class.h>
64 #include <obd_support.h>
65 #include <lustre/lustre_idl.h>
66 #include <lustre_sec.h>
67 #include <lustre_net.h>
68 #include <lustre_import.h>
69
70 #include "gss_err.h"
71 #include "gss_internal.h"
72 #include "gss_api.h"
73
74 static struct ptlrpc_sec_policy gss_policy_pipefs;
75 static struct ptlrpc_ctx_ops gss_pipefs_ctxops;
76
77 static int gss_cli_ctx_refresh_pf(struct ptlrpc_cli_ctx *ctx);
78
79 static int gss_sec_pipe_upcall_init(struct gss_sec *gsec)
80 {
81         return 0;
82 }
83
84 static void gss_sec_pipe_upcall_fini(struct gss_sec *gsec)
85 {
86 }
87
88 /****************************************
89  * internal context helpers             *
90  ****************************************/
91
92 static
93 struct ptlrpc_cli_ctx *ctx_create_pf(struct ptlrpc_sec *sec,
94                                      struct vfs_cred *vcred)
95 {
96         struct gss_cli_ctx *gctx;
97         int                 rc;
98
99         OBD_ALLOC_PTR(gctx);
100         if (gctx == NULL)
101                 return NULL;
102
103         rc = gss_cli_ctx_init_common(sec, &gctx->gc_base,
104                                      &gss_pipefs_ctxops, vcred);
105         if (rc) {
106                 OBD_FREE_PTR(gctx);
107                 return NULL;
108         }
109
110         return &gctx->gc_base;
111 }
112
113 static
114 void ctx_destroy_pf(struct ptlrpc_sec *sec, struct ptlrpc_cli_ctx *ctx)
115 {
116         struct gss_cli_ctx *gctx = ctx2gctx(ctx);
117
118         if (gss_cli_ctx_fini_common(sec, ctx))
119                 return;
120
121         OBD_FREE_PTR(gctx);
122
123         atomic_dec(&sec->ps_nctx);
124         sptlrpc_sec_put(sec);
125 }
126
127 static
128 void ctx_enhash_pf(struct ptlrpc_cli_ctx *ctx, struct hlist_head *hash)
129 {
130         set_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags);
131         atomic_inc(&ctx->cc_refcount);
132         hlist_add_head(&ctx->cc_cache, hash);
133 }
134
135 /*
136  * caller must hold spinlock
137  */
138 static
139 void ctx_unhash_pf(struct ptlrpc_cli_ctx *ctx, struct hlist_head *freelist)
140 {
141         assert_spin_locked(&ctx->cc_sec->ps_lock);
142         LASSERT(atomic_read(&ctx->cc_refcount) > 0);
143         LASSERT(test_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags));
144         LASSERT(!hlist_unhashed(&ctx->cc_cache));
145
146         clear_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags);
147
148         if (atomic_dec_and_test(&ctx->cc_refcount)) {
149                 __hlist_del(&ctx->cc_cache);
150                 hlist_add_head(&ctx->cc_cache, freelist);
151         } else {
152                 hlist_del_init(&ctx->cc_cache);
153         }
154 }
155
156 /*
157  * return 1 if the context is dead.
158  */
159 static
160 int ctx_check_death_pf(struct ptlrpc_cli_ctx *ctx,
161                        struct hlist_head *freelist)
162 {
163         if (cli_ctx_check_death(ctx)) {
164                 if (freelist)
165                         ctx_unhash_pf(ctx, freelist);
166                 return 1;
167         }
168
169         return 0;
170 }
171
172 static inline
173 int ctx_check_death_locked_pf(struct ptlrpc_cli_ctx *ctx,
174                               struct hlist_head *freelist)
175 {
176         LASSERT(ctx->cc_sec);
177         LASSERT(atomic_read(&ctx->cc_refcount) > 0);
178         LASSERT(test_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags));
179
180         return ctx_check_death_pf(ctx, freelist);
181 }
182
183 static inline
184 int ctx_match_pf(struct ptlrpc_cli_ctx *ctx, struct vfs_cred *vcred)
185 {
186         /* a little bit optimization for null policy */
187         if (!ctx->cc_ops->match)
188                 return 1;
189
190         return ctx->cc_ops->match(ctx, vcred);
191 }
192
193 static
194 void ctx_list_destroy_pf(struct hlist_head *head)
195 {
196         struct ptlrpc_cli_ctx *ctx;
197
198         while (!hlist_empty(head)) {
199                 ctx = cfs_hlist_entry(head->first, struct ptlrpc_cli_ctx,
200                                       cc_cache);
201
202                 LASSERT(atomic_read(&ctx->cc_refcount) == 0);
203                 LASSERT(test_bit(PTLRPC_CTX_CACHED_BIT,
204                                  &ctx->cc_flags) == 0);
205
206                 hlist_del_init(&ctx->cc_cache);
207                 ctx_destroy_pf(ctx->cc_sec, ctx);
208         }
209 }
210
211 /****************************************
212  * context apis                         *
213  ****************************************/
214
215 static
216 int gss_cli_ctx_validate_pf(struct ptlrpc_cli_ctx *ctx)
217 {
218         if (ctx_check_death_pf(ctx, NULL))
219                 return 1;
220         if (cli_ctx_is_ready(ctx))
221                 return 0;
222         return 1;
223 }
224
225 static
226 void gss_cli_ctx_die_pf(struct ptlrpc_cli_ctx *ctx, int grace)
227 {
228         LASSERT(ctx->cc_sec);
229         LASSERT(atomic_read(&ctx->cc_refcount) > 0);
230
231         cli_ctx_expire(ctx);
232
233         spin_lock(&ctx->cc_sec->ps_lock);
234
235         if (test_and_clear_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags)) {
236                 LASSERT(!hlist_unhashed(&ctx->cc_cache));
237                 LASSERT(atomic_read(&ctx->cc_refcount) > 1);
238
239                 hlist_del_init(&ctx->cc_cache);
240                 if (atomic_dec_and_test(&ctx->cc_refcount))
241                         LBUG();
242         }
243
244         spin_unlock(&ctx->cc_sec->ps_lock);
245 }
246
247 /****************************************
248  * reverse context installation         *
249  ****************************************/
250
251 static inline
252 unsigned int ctx_hash_index(int hashsize, __u64 key)
253 {
254         return (unsigned int) (key & ((__u64) hashsize - 1));
255 }
256
257 static
258 void gss_sec_ctx_replace_pf(struct gss_sec *gsec,
259                             struct ptlrpc_cli_ctx *new)
260 {
261         struct hlist_node __maybe_unused *pos, *next;
262         struct gss_sec_pipefs *gsec_pf;
263         struct ptlrpc_cli_ctx *ctx;
264         HLIST_HEAD(freelist);
265         unsigned int hash;
266         ENTRY;
267
268         gsec_pf = container_of(gsec, struct gss_sec_pipefs, gsp_base);
269
270         hash = ctx_hash_index(gsec_pf->gsp_chash_size,
271                               (__u64) new->cc_vcred.vc_uid);
272         LASSERT(hash < gsec_pf->gsp_chash_size);
273
274         spin_lock(&gsec->gs_base.ps_lock);
275
276         cfs_hlist_for_each_entry_safe(ctx, pos, next,
277                                       &gsec_pf->gsp_chash[hash], cc_cache) {
278                 if (!ctx_match_pf(ctx, &new->cc_vcred))
279                         continue;
280
281                 cli_ctx_expire(ctx);
282                 ctx_unhash_pf(ctx, &freelist);
283                 break;
284         }
285
286         ctx_enhash_pf(new, &gsec_pf->gsp_chash[hash]);
287
288         spin_unlock(&gsec->gs_base.ps_lock);
289
290         ctx_list_destroy_pf(&freelist);
291         EXIT;
292 }
293
294 static
295 int gss_install_rvs_cli_ctx_pf(struct gss_sec *gsec,
296                                struct ptlrpc_svc_ctx *svc_ctx)
297 {
298         struct vfs_cred          vcred;
299         struct ptlrpc_cli_ctx   *cli_ctx;
300         int                      rc;
301         ENTRY;
302
303         vcred.vc_uid = 0;
304         vcred.vc_gid = 0;
305
306         cli_ctx = ctx_create_pf(&gsec->gs_base, &vcred);
307         if (!cli_ctx)
308                 RETURN(-ENOMEM);
309
310         rc = gss_copy_rvc_cli_ctx(cli_ctx, svc_ctx);
311         if (rc) {
312                 ctx_destroy_pf(cli_ctx->cc_sec, cli_ctx);
313                 RETURN(rc);
314         }
315
316         gss_sec_ctx_replace_pf(gsec, cli_ctx);
317         RETURN(0);
318 }
319
320 static
321 void gss_ctx_cache_gc_pf(struct gss_sec_pipefs *gsec_pf,
322                          struct hlist_head *freelist)
323 {
324         struct ptlrpc_sec       *sec;
325         struct ptlrpc_cli_ctx   *ctx;
326         struct hlist_node       __maybe_unused *pos;
327         struct hlist_node       *next;
328         int i;
329         ENTRY;
330
331         sec = &gsec_pf->gsp_base.gs_base;
332
333         CDEBUG(D_SEC, "do gc on sec %s@%p\n", sec->ps_policy->sp_name, sec);
334
335         for (i = 0; i < gsec_pf->gsp_chash_size; i++) {
336                 cfs_hlist_for_each_entry_safe(ctx, pos, next,
337                                               &gsec_pf->gsp_chash[i], cc_cache)
338                         ctx_check_death_locked_pf(ctx, freelist);
339         }
340
341         sec->ps_gc_next = ktime_get_real_seconds() + sec->ps_gc_interval;
342         EXIT;
343 }
344
345 static
346 struct ptlrpc_sec* gss_sec_create_pf(struct obd_import *imp,
347                                      struct ptlrpc_svc_ctx *ctx,
348                                      struct sptlrpc_flavor *sf)
349 {
350         struct gss_sec_pipefs   *gsec_pf;
351         int                      alloc_size, hash_size, i;
352         ENTRY;
353
354 #define GSS_SEC_PIPEFS_CTX_HASH_SIZE    (32)
355
356         if (ctx ||
357             sf->sf_flags & (PTLRPC_SEC_FL_ROOTONLY | PTLRPC_SEC_FL_REVERSE))
358                 hash_size = 1;
359         else
360                 hash_size = GSS_SEC_PIPEFS_CTX_HASH_SIZE;
361
362         alloc_size = sizeof(*gsec_pf) +
363                      sizeof(struct hlist_head) * hash_size;
364
365         OBD_ALLOC(gsec_pf, alloc_size);
366         if (!gsec_pf)
367                 RETURN(NULL);
368
369         gsec_pf->gsp_chash_size = hash_size;
370         for (i = 0; i < hash_size; i++)
371                 INIT_HLIST_HEAD(&gsec_pf->gsp_chash[i]);
372
373         if (gss_sec_create_common(&gsec_pf->gsp_base, &gss_policy_pipefs,
374                                   imp, ctx, sf))
375                 goto err_free;
376
377         if (ctx == NULL) {
378                 if (gss_sec_pipe_upcall_init(&gsec_pf->gsp_base))
379                         goto err_destroy;
380         } else {
381                 if (gss_install_rvs_cli_ctx_pf(&gsec_pf->gsp_base, ctx))
382                         goto err_destroy;
383         }
384
385         RETURN(&gsec_pf->gsp_base.gs_base);
386
387 err_destroy:
388         gss_sec_destroy_common(&gsec_pf->gsp_base);
389 err_free:
390         OBD_FREE(gsec_pf, alloc_size);
391         RETURN(NULL);
392 }
393
394 static
395 void gss_sec_destroy_pf(struct ptlrpc_sec *sec)
396 {
397         struct gss_sec_pipefs   *gsec_pf;
398         struct gss_sec          *gsec;
399
400         CWARN("destroy %s@%p\n", sec->ps_policy->sp_name, sec);
401
402         gsec = container_of(sec, struct gss_sec, gs_base);
403         gsec_pf = container_of(gsec, struct gss_sec_pipefs, gsp_base);
404
405         LASSERT(gsec_pf->gsp_chash);
406         LASSERT(gsec_pf->gsp_chash_size);
407
408         gss_sec_pipe_upcall_fini(gsec);
409
410         gss_sec_destroy_common(gsec);
411
412         OBD_FREE(gsec, sizeof(*gsec_pf) +
413                        sizeof(struct hlist_head) * gsec_pf->gsp_chash_size);
414 }
415
416 static
417 struct ptlrpc_cli_ctx * gss_sec_lookup_ctx_pf(struct ptlrpc_sec *sec,
418                                               struct vfs_cred *vcred,
419                                               int create, int remove_dead)
420 {
421         struct gss_sec          *gsec;
422         struct gss_sec_pipefs   *gsec_pf;
423         struct ptlrpc_cli_ctx   *ctx = NULL, *new = NULL;
424         struct hlist_head       *hash_head;
425         struct hlist_node       __maybe_unused *pos, *next;
426         unsigned int            hash, gc = 0, found = 0;
427         HLIST_HEAD(freelist);
428         ENTRY;
429
430         might_sleep();
431
432         gsec = container_of(sec, struct gss_sec, gs_base);
433         gsec_pf = container_of(gsec, struct gss_sec_pipefs, gsp_base);
434
435         hash = ctx_hash_index(gsec_pf->gsp_chash_size,
436                               (__u64) vcred->vc_uid);
437         hash_head = &gsec_pf->gsp_chash[hash];
438         LASSERT(hash < gsec_pf->gsp_chash_size);
439
440 retry:
441         spin_lock(&sec->ps_lock);
442
443         /* gc_next == 0 means never do gc */
444         if (remove_dead && sec->ps_gc_next &&
445            (ktime_get_real_seconds() > sec->ps_gc_next)) {
446                 gss_ctx_cache_gc_pf(gsec_pf, &freelist);
447                 gc = 1;
448         }
449
450         cfs_hlist_for_each_entry_safe(ctx, pos, next, hash_head, cc_cache) {
451                 if (gc == 0 &&
452                     ctx_check_death_locked_pf(ctx,
453                                               remove_dead ? &freelist : NULL))
454                         continue;
455
456                 if (ctx_match_pf(ctx, vcred)) {
457                         found = 1;
458                         break;
459                 }
460         }
461
462         if (found) {
463                 if (new && new != ctx) {
464                         /* lost the race, just free it */
465                         hlist_add_head(&new->cc_cache, &freelist);
466                         new = NULL;
467                 }
468
469                 /* hot node, move to head */
470                 if (hash_head->first != &ctx->cc_cache) {
471                         __hlist_del(&ctx->cc_cache);
472                         hlist_add_head(&ctx->cc_cache, hash_head);
473                 }
474         } else {
475                 /* don't allocate for reverse sec */
476                 if (sec_is_reverse(sec)) {
477                         spin_unlock(&sec->ps_lock);
478                         RETURN(NULL);
479                 }
480
481                 if (new) {
482                         ctx_enhash_pf(new, hash_head);
483                         ctx = new;
484                 } else if (create) {
485                         spin_unlock(&sec->ps_lock);
486                         new = ctx_create_pf(sec, vcred);
487                         if (new) {
488                                 clear_bit(PTLRPC_CTX_NEW_BIT, &new->cc_flags);
489                                 goto retry;
490                         }
491                 } else {
492                         ctx = NULL;
493                 }
494         }
495
496         /* hold a ref */
497         if (ctx)
498                 atomic_inc(&ctx->cc_refcount);
499
500         spin_unlock(&sec->ps_lock);
501
502         /* the allocator of the context must give the first push to refresh */
503         if (new) {
504                 LASSERT(new == ctx);
505                 gss_cli_ctx_refresh_pf(new);
506         }
507
508         ctx_list_destroy_pf(&freelist);
509         RETURN(ctx);
510 }
511
512 static
513 void gss_sec_release_ctx_pf(struct ptlrpc_sec *sec,
514                             struct ptlrpc_cli_ctx *ctx,
515                             int sync)
516 {
517         LASSERT(test_bit(PTLRPC_CTX_CACHED_BIT, &ctx->cc_flags) == 0);
518         LASSERT(hlist_unhashed(&ctx->cc_cache));
519
520         /* if required async, we must clear the UPTODATE bit to prevent extra
521          * rpcs during destroy procedure. */
522         if (!sync)
523                 clear_bit(PTLRPC_CTX_UPTODATE_BIT, &ctx->cc_flags);
524
525         /* destroy this context */
526         ctx_destroy_pf(sec, ctx);
527 }
528
529 /*
530  * @uid: which user. "-1" means flush all.
531  * @grace: mark context DEAD, allow graceful destroy like notify
532  *         server side, etc.
533  * @force: also flush busy entries.
534  *
535  * return the number of busy context encountered.
536  *
537  * In any cases, never touch "eternal" contexts.
538  */
539 static
540 int gss_sec_flush_ctx_cache_pf(struct ptlrpc_sec *sec,
541                                uid_t uid,
542                                int grace, int force)
543 {
544         struct gss_sec          *gsec;
545         struct gss_sec_pipefs   *gsec_pf;
546         struct ptlrpc_cli_ctx   *ctx;
547         struct hlist_node       __maybe_unused *pos, *next;
548         HLIST_HEAD(freelist);
549         int i, busy = 0;
550         ENTRY;
551
552         might_sleep_if(grace);
553
554         gsec = container_of(sec, struct gss_sec, gs_base);
555         gsec_pf = container_of(gsec, struct gss_sec_pipefs, gsp_base);
556
557         spin_lock(&sec->ps_lock);
558         for (i = 0; i < gsec_pf->gsp_chash_size; i++) {
559                 cfs_hlist_for_each_entry_safe(ctx, pos, next,
560                                               &gsec_pf->gsp_chash[i],
561                                               cc_cache) {
562                         LASSERT(atomic_read(&ctx->cc_refcount) > 0);
563
564                         if (uid != -1 && uid != ctx->cc_vcred.vc_uid)
565                                 continue;
566
567                         if (atomic_read(&ctx->cc_refcount) > 1) {
568                                 busy++;
569                                 if (!force)
570                                         continue;
571
572                                 CWARN("flush busy(%d) ctx %p(%u->%s) by force, "
573                                       "grace %d\n",
574                                       atomic_read(&ctx->cc_refcount),
575                                       ctx, ctx->cc_vcred.vc_uid,
576                                       sec2target_str(ctx->cc_sec), grace);
577                         }
578                         ctx_unhash_pf(ctx, &freelist);
579
580                         set_bit(PTLRPC_CTX_DEAD_BIT, &ctx->cc_flags);
581                         if (!grace)
582                                 clear_bit(PTLRPC_CTX_UPTODATE_BIT,
583                                           &ctx->cc_flags);
584                 }
585         }
586         spin_unlock(&sec->ps_lock);
587
588         ctx_list_destroy_pf(&freelist);
589         RETURN(busy);
590 }
591
592 /****************************************
593  * service apis                         *
594  ****************************************/
595
596 static
597 int gss_svc_accept_pf(struct ptlrpc_request *req)
598 {
599         return gss_svc_accept(&gss_policy_pipefs, req);
600 }
601
602 static
603 int gss_svc_install_rctx_pf(struct obd_import *imp,
604                             struct ptlrpc_svc_ctx *ctx)
605 {
606         struct ptlrpc_sec *sec;
607         int                rc;
608
609         sec = sptlrpc_import_sec_ref(imp);
610         LASSERT(sec);
611         rc = gss_install_rvs_cli_ctx_pf(sec2gsec(sec), ctx);
612
613         sptlrpc_sec_put(sec);
614         return rc;
615 }
616
617 /****************************************
618  * rpc_pipefs definitions               *
619  ****************************************/
620
621 #define LUSTRE_PIPE_ROOT        "/lustre"
622 #define LUSTRE_PIPE_KRB5        LUSTRE_PIPE_ROOT"/krb5"
623
624 struct gss_upcall_msg_data {
625         __u32                           gum_seq;
626         __u32                           gum_uid;
627         __u32                           gum_gid;
628         __u32                           gum_svc;        /* MDS/OSS... */
629         __u64                           gum_nid;        /* peer NID */
630         __u8                            gum_obd[64];    /* client obd name */
631 };
632
633 struct gss_upcall_msg {
634         struct rpc_pipe_msg             gum_base;
635         atomic_t                        gum_refcount;
636         struct list_head                gum_list;
637         __u32                           gum_mechidx;
638         struct gss_sec                  *gum_gsec;
639         struct gss_cli_ctx              *gum_gctx;
640         struct gss_upcall_msg_data      gum_data;
641 };
642
643 static atomic_t upcall_seq = ATOMIC_INIT(0);
644
645 static inline
646 __u32 upcall_get_sequence(void)
647 {
648         return (__u32) atomic_inc_return(&upcall_seq);
649 }
650
651 enum mech_idx_t {
652         MECH_KRB5   = 0,
653         MECH_MAX
654 };
655
656 static inline
657 __u32 mech_name2idx(const char *name)
658 {
659         LASSERT(!strcmp(name, "krb5"));
660         return MECH_KRB5;
661 }
662
663 /* pipefs dentries for each mechanisms */
664 static struct dentry *de_pipes[MECH_MAX] = { NULL, };
665 /* all upcall messgaes linked here */
666 static struct list_head upcall_lists[MECH_MAX];
667 /* and protected by this */
668 static spinlock_t upcall_locks[MECH_MAX];
669
670 static inline
671 void upcall_list_lock(int idx)
672 {
673         spin_lock(&upcall_locks[idx]);
674 }
675
676 static inline
677 void upcall_list_unlock(int idx)
678 {
679         spin_unlock(&upcall_locks[idx]);
680 }
681
682 static
683 void upcall_msg_enlist(struct gss_upcall_msg *msg)
684 {
685         __u32 idx = msg->gum_mechidx;
686
687         upcall_list_lock(idx);
688         list_add(&msg->gum_list, &upcall_lists[idx]);
689         upcall_list_unlock(idx);
690 }
691
692 static
693 void upcall_msg_delist(struct gss_upcall_msg *msg)
694 {
695         __u32 idx = msg->gum_mechidx;
696
697         upcall_list_lock(idx);
698         list_del_init(&msg->gum_list);
699         upcall_list_unlock(idx);
700 }
701
702 /****************************************
703  * rpc_pipefs upcall helpers            *
704  ****************************************/
705
706 static
707 void gss_release_msg(struct gss_upcall_msg *gmsg)
708 {
709         ENTRY;
710         LASSERT(atomic_read(&gmsg->gum_refcount) > 0);
711
712         if (!atomic_dec_and_test(&gmsg->gum_refcount)) {
713                 EXIT;
714                 return;
715         }
716
717         if (gmsg->gum_gctx) {
718                 sptlrpc_cli_ctx_wakeup(&gmsg->gum_gctx->gc_base);
719                 sptlrpc_cli_ctx_put(&gmsg->gum_gctx->gc_base, 1);
720                 gmsg->gum_gctx = NULL;
721         }
722
723         LASSERT(list_empty(&gmsg->gum_list));
724         LASSERT(list_empty(&gmsg->gum_base.list));
725         OBD_FREE_PTR(gmsg);
726         EXIT;
727 }
728
729 static
730 void gss_unhash_msg_nolock(struct gss_upcall_msg *gmsg)
731 {
732         __u32 idx = gmsg->gum_mechidx;
733
734         LASSERT(idx < MECH_MAX);
735         assert_spin_locked(&upcall_locks[idx]);
736
737         if (list_empty(&gmsg->gum_list))
738                 return;
739
740         list_del_init(&gmsg->gum_list);
741         LASSERT(atomic_read(&gmsg->gum_refcount) > 1);
742         atomic_dec(&gmsg->gum_refcount);
743 }
744
745 static
746 void gss_unhash_msg(struct gss_upcall_msg *gmsg)
747 {
748         __u32 idx = gmsg->gum_mechidx;
749
750         LASSERT(idx < MECH_MAX);
751         upcall_list_lock(idx);
752         gss_unhash_msg_nolock(gmsg);
753         upcall_list_unlock(idx);
754 }
755
756 static
757 void gss_msg_fail_ctx(struct gss_upcall_msg *gmsg)
758 {
759         if (gmsg->gum_gctx) {
760                 struct ptlrpc_cli_ctx *ctx = &gmsg->gum_gctx->gc_base;
761
762                 LASSERT(atomic_read(&ctx->cc_refcount) > 0);
763                 sptlrpc_cli_ctx_expire(ctx);
764                 set_bit(PTLRPC_CTX_ERROR_BIT, &ctx->cc_flags);
765         }
766 }
767
768 static
769 struct gss_upcall_msg * gss_find_upcall(__u32 mechidx, __u32 seq)
770 {
771         struct gss_upcall_msg *gmsg;
772
773         upcall_list_lock(mechidx);
774         list_for_each_entry(gmsg, &upcall_lists[mechidx], gum_list) {
775                 if (gmsg->gum_data.gum_seq != seq)
776                         continue;
777
778                 LASSERT(atomic_read(&gmsg->gum_refcount) > 0);
779                 LASSERT(gmsg->gum_mechidx == mechidx);
780
781                 atomic_inc(&gmsg->gum_refcount);
782                 upcall_list_unlock(mechidx);
783                 return gmsg;
784         }
785         upcall_list_unlock(mechidx);
786         return NULL;
787 }
788
789 static
790 int simple_get_bytes(char **buf, __u32 *buflen, void *res, __u32 reslen)
791 {
792         if (*buflen < reslen) {
793                 CERROR("buflen %u < %u\n", *buflen, reslen);
794                 return -EINVAL;
795         }
796
797         memcpy(res, *buf, reslen);
798         *buf += reslen;
799         *buflen -= reslen;
800         return 0;
801 }
802
803 /****************************************
804  * rpc_pipefs apis                      *
805  ****************************************/
806
807 static
808 ssize_t gss_pipe_upcall(struct file *filp, struct rpc_pipe_msg *msg,
809                         char *dst, size_t buflen)
810 {
811         char *data = (char *)msg->data + msg->copied;
812         ssize_t mlen = msg->len;
813         ssize_t left;
814         ENTRY;
815
816         if (mlen > buflen)
817                 mlen = buflen;
818         left = copy_to_user(dst, data, mlen);
819         if (left < 0) {
820                 msg->errno = left;
821                 RETURN(left);
822         }
823         mlen -= left;
824         msg->copied += mlen;
825         msg->errno = 0;
826         RETURN(mlen);
827 }
828
829 static
830 ssize_t gss_pipe_downcall(struct file *filp, const char *src, size_t mlen)
831 {
832         struct rpc_inode        *rpci = RPC_I(file_inode(filp));
833         struct gss_upcall_msg   *gss_msg;
834         struct ptlrpc_cli_ctx   *ctx;
835         struct gss_cli_ctx      *gctx = NULL;
836         char                    *buf, *data;
837         int                      datalen;
838         int                      timeout, rc;
839         __u32                    mechidx, seq, gss_err;
840         ENTRY;
841
842         mechidx = (__u32) (long) rpci->private;
843         LASSERT(mechidx < MECH_MAX);
844
845         OBD_ALLOC(buf, mlen);
846         if (!buf)
847                 RETURN(-ENOMEM);
848
849         if (copy_from_user(buf, src, mlen)) {
850                 CERROR("failed copy user space data\n");
851                 GOTO(out_free, rc = -EFAULT);
852         }
853         data = buf;
854         datalen = mlen;
855
856         /* data passed down format:
857          *  - seq
858          *  - timeout
859          *  - gc_win / error
860          *  - wire_ctx (rawobj)
861          *  - mech_ctx (rawobj)
862          */
863         if (simple_get_bytes(&data, &datalen, &seq, sizeof(seq))) {
864                 CERROR("fail to get seq\n");
865                 GOTO(out_free, rc = -EFAULT);
866         }
867
868         gss_msg = gss_find_upcall(mechidx, seq);
869         if (!gss_msg) {
870                 CERROR("upcall %u has aborted earlier\n", seq);
871                 GOTO(out_free, rc = -EINVAL);
872         }
873
874         gss_unhash_msg(gss_msg);
875         gctx = gss_msg->gum_gctx;
876         LASSERT(gctx);
877         LASSERT(atomic_read(&gctx->gc_base.cc_refcount) > 0);
878
879         /* timeout is not in use for now */
880         if (simple_get_bytes(&data, &datalen, &timeout, sizeof(timeout)))
881                 GOTO(out_msg, rc = -EFAULT);
882
883         /* lgssd signal an error by gc_win == 0 */
884         if (simple_get_bytes(&data, &datalen, &gctx->gc_win,
885                              sizeof(gctx->gc_win)))
886                 GOTO(out_msg, rc = -EFAULT);
887
888         if (gctx->gc_win == 0) {
889                 /* followed by:
890                  * - rpc error
891                  * - gss error
892                  */
893                 if (simple_get_bytes(&data, &datalen, &rc, sizeof(rc)))
894                         GOTO(out_msg, rc = -EFAULT);
895                 if (simple_get_bytes(&data, &datalen, &gss_err,sizeof(gss_err)))
896                         GOTO(out_msg, rc = -EFAULT);
897
898                 if (rc == 0 && gss_err == GSS_S_COMPLETE) {
899                         CWARN("both rpc & gss error code not set\n");
900                         rc = -EPERM;
901                 }
902         } else {
903                 rawobj_t tmpobj;
904
905                 /* handle */
906                 if (rawobj_extract_local(&tmpobj, (__u32 **) &data, &datalen))
907                         GOTO(out_msg, rc = -EFAULT);
908                 if (rawobj_dup(&gctx->gc_handle, &tmpobj))
909                         GOTO(out_msg, rc = -ENOMEM);
910
911                 /* mechctx */
912                 if (rawobj_extract_local(&tmpobj, (__u32 **) &data, &datalen))
913                         GOTO(out_msg, rc = -EFAULT);
914                 gss_err = lgss_import_sec_context(&tmpobj,
915                                                   gss_msg->gum_gsec->gs_mech,
916                                                   &gctx->gc_mechctx);
917                 rc = 0;
918         }
919
920         if (likely(rc == 0 && gss_err == GSS_S_COMPLETE)) {
921                 gss_cli_ctx_uptodate(gctx);
922         } else {
923                 ctx = &gctx->gc_base;
924                 sptlrpc_cli_ctx_expire(ctx);
925                 if (rc != -ERESTART || gss_err != GSS_S_COMPLETE)
926                         set_bit(PTLRPC_CTX_ERROR_BIT, &ctx->cc_flags);
927
928                 CERROR("refresh ctx %p(uid %d) failed: %d/0x%08x: %s\n",
929                        ctx, ctx->cc_vcred.vc_uid, rc, gss_err,
930                        test_bit(PTLRPC_CTX_ERROR_BIT, &ctx->cc_flags) ?
931                        "fatal error" : "non-fatal");
932         }
933
934         rc = mlen;
935
936 out_msg:
937         gss_release_msg(gss_msg);
938
939 out_free:
940         OBD_FREE(buf, mlen);
941         /* FIXME
942          * hack pipefs: always return asked length unless all following
943          * downcalls might be messed up. */
944         rc = mlen;
945         RETURN(rc);
946 }
947
948 static
949 void gss_pipe_destroy_msg(struct rpc_pipe_msg *msg)
950 {
951         struct gss_upcall_msg          *gmsg;
952         struct gss_upcall_msg_data     *gumd;
953         static time64_t ratelimit;
954         ENTRY;
955
956         LASSERT(list_empty(&msg->list));
957
958         /* normally errno is >= 0 */
959         if (msg->errno >= 0) {
960                 EXIT;
961                 return;
962         }
963
964         gmsg = container_of(msg, struct gss_upcall_msg, gum_base);
965         gumd = &gmsg->gum_data;
966         LASSERT(atomic_read(&gmsg->gum_refcount) > 0);
967
968         CERROR("failed msg %p (seq %u, uid %u, svc %u, nid %#llx, obd %.*s): "
969                "errno %d\n", msg, gumd->gum_seq, gumd->gum_uid, gumd->gum_svc,
970                gumd->gum_nid, (int) sizeof(gumd->gum_obd),
971                gumd->gum_obd, msg->errno);
972
973         atomic_inc(&gmsg->gum_refcount);
974         gss_unhash_msg(gmsg);
975         if (msg->errno == -ETIMEDOUT || msg->errno == -EPIPE) {
976                 time64_t now = ktime_get_real_seconds();
977
978                 if (now > ratelimit) {
979                         CWARN("upcall timed out, is lgssd running?\n");
980                         ratelimit = now + 15;
981                 }
982         }
983         gss_msg_fail_ctx(gmsg);
984         gss_release_msg(gmsg);
985         EXIT;
986 }
987
988 static
989 void gss_pipe_release(struct inode *inode)
990 {
991         struct rpc_inode *rpci = RPC_I(inode);
992         __u32             idx;
993         ENTRY;
994
995         idx = (__u32) (long) rpci->private;
996         LASSERT(idx < MECH_MAX);
997
998         upcall_list_lock(idx);
999         while (!list_empty(&upcall_lists[idx])) {
1000                 struct gss_upcall_msg      *gmsg;
1001                 struct gss_upcall_msg_data *gumd;
1002
1003                 gmsg = list_entry(upcall_lists[idx].next,
1004                                   struct gss_upcall_msg, gum_list);
1005                 gumd = &gmsg->gum_data;
1006                 LASSERT(list_empty(&gmsg->gum_base.list));
1007
1008                 CERROR("failing remaining msg %p:seq %u, uid %u, svc %u, "
1009                        "nid %#llx, obd %.*s\n", gmsg,
1010                        gumd->gum_seq, gumd->gum_uid, gumd->gum_svc,
1011                        gumd->gum_nid, (int) sizeof(gumd->gum_obd),
1012                        gumd->gum_obd);
1013
1014                 gmsg->gum_base.errno = -EPIPE;
1015                 atomic_inc(&gmsg->gum_refcount);
1016                 gss_unhash_msg_nolock(gmsg);
1017
1018                 gss_msg_fail_ctx(gmsg);
1019
1020                 upcall_list_unlock(idx);
1021                 gss_release_msg(gmsg);
1022                 upcall_list_lock(idx);
1023         }
1024         upcall_list_unlock(idx);
1025         EXIT;
1026 }
1027
1028 static struct rpc_pipe_ops gss_upcall_ops = {
1029         .upcall         = gss_pipe_upcall,
1030         .downcall       = gss_pipe_downcall,
1031         .destroy_msg    = gss_pipe_destroy_msg,
1032         .release_pipe   = gss_pipe_release,
1033 };
1034
1035 /****************************************
1036  * upcall helper functions              *
1037  ****************************************/
1038
1039 static
1040 int gss_ctx_refresh_pf(struct ptlrpc_cli_ctx *ctx)
1041 {
1042         struct obd_import          *imp;
1043         struct gss_sec             *gsec;
1044         struct gss_upcall_msg      *gmsg;
1045         int                         rc = 0;
1046         ENTRY;
1047
1048         might_sleep();
1049
1050         LASSERT(ctx->cc_sec);
1051         LASSERT(ctx->cc_sec->ps_import);
1052         LASSERT(ctx->cc_sec->ps_import->imp_obd);
1053
1054         imp = ctx->cc_sec->ps_import;
1055         if (!imp->imp_connection) {
1056                 CERROR("import has no connection set\n");
1057                 RETURN(-EINVAL);
1058         }
1059
1060         gsec = container_of(ctx->cc_sec, struct gss_sec, gs_base);
1061
1062         OBD_ALLOC_PTR(gmsg);
1063         if (!gmsg)
1064                 RETURN(-ENOMEM);
1065
1066         /* initialize pipefs base msg */
1067         INIT_LIST_HEAD(&gmsg->gum_base.list);
1068         gmsg->gum_base.data = &gmsg->gum_data;
1069         gmsg->gum_base.len = sizeof(gmsg->gum_data);
1070         gmsg->gum_base.copied = 0;
1071         gmsg->gum_base.errno = 0;
1072
1073         /* init upcall msg */
1074         atomic_set(&gmsg->gum_refcount, 1);
1075         gmsg->gum_mechidx = mech_name2idx(gsec->gs_mech->gm_name);
1076         gmsg->gum_gsec = gsec;
1077         gmsg->gum_gctx = container_of(sptlrpc_cli_ctx_get(ctx),
1078                                       struct gss_cli_ctx, gc_base);
1079         gmsg->gum_data.gum_seq = upcall_get_sequence();
1080         gmsg->gum_data.gum_uid = ctx->cc_vcred.vc_uid;
1081         gmsg->gum_data.gum_gid = 0; /* not used for now */
1082         gmsg->gum_data.gum_svc = import_to_gss_svc(imp);
1083         gmsg->gum_data.gum_nid = imp->imp_connection->c_peer.nid;
1084         strlcpy(gmsg->gum_data.gum_obd, imp->imp_obd->obd_name,
1085                 sizeof(gmsg->gum_data.gum_obd));
1086
1087         /* This only could happen when sysadmin set it dead/expired
1088          * using lctl by force. */
1089         if (ctx->cc_flags & PTLRPC_CTX_STATUS_MASK) {
1090                 CWARN("ctx %p(%u->%s) was set flags %lx unexpectedly\n",
1091                       ctx, ctx->cc_vcred.vc_uid, sec2target_str(ctx->cc_sec),
1092                       ctx->cc_flags);
1093
1094                 LASSERT(!(ctx->cc_flags & PTLRPC_CTX_UPTODATE));
1095                 ctx->cc_flags |= PTLRPC_CTX_DEAD | PTLRPC_CTX_ERROR;
1096
1097                 rc = -EIO;
1098                 goto err_free;
1099         }
1100
1101         upcall_msg_enlist(gmsg);
1102
1103         rc = rpc_queue_upcall(de_pipes[gmsg->gum_mechidx]->d_inode,
1104                               &gmsg->gum_base);
1105         if (rc) {
1106                 CERROR("rpc_queue_upcall failed: %d\n", rc);
1107
1108                 upcall_msg_delist(gmsg);
1109                 goto err_free;
1110         }
1111
1112         RETURN(0);
1113 err_free:
1114         OBD_FREE_PTR(gmsg);
1115         RETURN(rc);
1116 }
1117
1118 static
1119 int gss_cli_ctx_refresh_pf(struct ptlrpc_cli_ctx *ctx)
1120 {
1121         /* if we are refreshing for root, also update the reverse
1122          * handle index, do not confuse reverse contexts. */
1123         if (ctx->cc_vcred.vc_uid == 0) {
1124                 struct gss_sec *gsec;
1125
1126                 gsec = container_of(ctx->cc_sec, struct gss_sec, gs_base);
1127                 gsec->gs_rvs_hdl = gss_get_next_ctx_index();
1128         }
1129
1130         return gss_ctx_refresh_pf(ctx);
1131 }
1132
1133 /****************************************
1134  * lustre gss pipefs policy             *
1135  ****************************************/
1136
1137 static struct ptlrpc_ctx_ops gss_pipefs_ctxops = {
1138         .match                  = gss_cli_ctx_match,
1139         .refresh                = gss_cli_ctx_refresh_pf,
1140         .validate               = gss_cli_ctx_validate_pf,
1141         .die                    = gss_cli_ctx_die_pf,
1142         .sign                   = gss_cli_ctx_sign,
1143         .verify                 = gss_cli_ctx_verify,
1144         .seal                   = gss_cli_ctx_seal,
1145         .unseal                 = gss_cli_ctx_unseal,
1146         .wrap_bulk              = gss_cli_ctx_wrap_bulk,
1147         .unwrap_bulk            = gss_cli_ctx_unwrap_bulk,
1148 };
1149
1150 static struct ptlrpc_sec_cops gss_sec_pipefs_cops = {
1151         .create_sec             = gss_sec_create_pf,
1152         .destroy_sec            = gss_sec_destroy_pf,
1153         .kill_sec               = gss_sec_kill,
1154         .lookup_ctx             = gss_sec_lookup_ctx_pf,
1155         .release_ctx            = gss_sec_release_ctx_pf,
1156         .flush_ctx_cache        = gss_sec_flush_ctx_cache_pf,
1157         .install_rctx           = gss_sec_install_rctx,
1158         .alloc_reqbuf           = gss_alloc_reqbuf,
1159         .free_reqbuf            = gss_free_reqbuf,
1160         .alloc_repbuf           = gss_alloc_repbuf,
1161         .free_repbuf            = gss_free_repbuf,
1162         .enlarge_reqbuf         = gss_enlarge_reqbuf,
1163 };
1164
1165 static struct ptlrpc_sec_sops gss_sec_pipefs_sops = {
1166         .accept                 = gss_svc_accept_pf,
1167         .invalidate_ctx         = gss_svc_invalidate_ctx,
1168         .alloc_rs               = gss_svc_alloc_rs,
1169         .authorize              = gss_svc_authorize,
1170         .free_rs                = gss_svc_free_rs,
1171         .free_ctx               = gss_svc_free_ctx,
1172         .unwrap_bulk            = gss_svc_unwrap_bulk,
1173         .wrap_bulk              = gss_svc_wrap_bulk,
1174         .install_rctx           = gss_svc_install_rctx_pf,
1175 };
1176
1177 static struct ptlrpc_sec_policy gss_policy_pipefs = {
1178         .sp_owner               = THIS_MODULE,
1179         .sp_name                = "gss.pipefs",
1180         .sp_policy              = SPTLRPC_POLICY_GSS_PIPEFS,
1181         .sp_cops                = &gss_sec_pipefs_cops,
1182         .sp_sops                = &gss_sec_pipefs_sops,
1183 };
1184
1185 static
1186 int __init gss_init_pipefs_upcall(void)
1187 {
1188         struct dentry   *de;
1189
1190         /* pipe dir */
1191         de = rpc_mkdir(LUSTRE_PIPE_ROOT, NULL);
1192         if (IS_ERR(de) && PTR_ERR(de) != -EEXIST) {
1193                 CERROR("Failed to create gss pipe dir: %ld\n", PTR_ERR(de));
1194                 return PTR_ERR(de);
1195         }
1196
1197         /* FIXME hack pipefs: dput will sometimes cause oops during module
1198          * unload and lgssd close the pipe fds. */
1199
1200         /* krb5 mechanism */
1201         de = rpc_mkpipe(LUSTRE_PIPE_KRB5, (void *) MECH_KRB5, &gss_upcall_ops,
1202                         RPC_PIPE_WAIT_FOR_OPEN);
1203         if (!de || IS_ERR(de)) {
1204                 CERROR("failed to make rpc_pipe %s: %ld\n",
1205                        LUSTRE_PIPE_KRB5, PTR_ERR(de));
1206                 rpc_rmdir(LUSTRE_PIPE_ROOT);
1207                 return PTR_ERR(de);
1208         }
1209
1210         de_pipes[MECH_KRB5] = de;
1211         INIT_LIST_HEAD(&upcall_lists[MECH_KRB5]);
1212         spin_lock_init(&upcall_locks[MECH_KRB5]);
1213
1214         return 0;
1215 }
1216
1217 static
1218 void __exit gss_exit_pipefs_upcall(void)
1219 {
1220         __u32 i;
1221
1222         for (i = 0; i < MECH_MAX; i++) {
1223                 LASSERT(list_empty(&upcall_lists[i]));
1224
1225                 /* dput pipe dentry here might cause lgssd oops. */
1226                 de_pipes[i] = NULL;
1227         }
1228
1229         rpc_unlink(LUSTRE_PIPE_KRB5);
1230         rpc_rmdir(LUSTRE_PIPE_ROOT);
1231 }
1232
1233 int __init gss_init_pipefs(void)
1234 {
1235         int rc;
1236
1237         rc = gss_init_pipefs_upcall();
1238         if (rc)
1239                 return rc;
1240
1241         rc = sptlrpc_register_policy(&gss_policy_pipefs);
1242         if (rc) {
1243                 gss_exit_pipefs_upcall();
1244                 return rc;
1245         }
1246
1247         return 0;
1248 }
1249
1250 void __exit gss_exit_pipefs(void)
1251 {
1252         gss_exit_pipefs_upcall();
1253         sptlrpc_unregister_policy(&gss_policy_pipefs);
1254 }