Whamcloud - gitweb
branch: HEAD
[fs/lustre-release.git] / lustre / ptlrpc / sec.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Copyright (C) 2004-2006 Cluster File Systems, Inc.
5  *
6  *   This file is part of Lustre, http://www.lustre.org.
7  *
8  *   Lustre is free software; you can redistribute it and/or
9  *   modify it under the terms of version 2 of the GNU General Public
10  *   License as published by the Free Software Foundation.
11  *
12  *   Lustre is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with Lustre; if not, write to the Free Software
19  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 #ifndef EXPORT_SYMTAB
23 #define EXPORT_SYMTAB
24 #endif
25 #define DEBUG_SUBSYSTEM S_SEC
26
27 #include <libcfs/libcfs.h>
28 #ifndef __KERNEL__
29 #include <liblustre.h>
30 #include <libcfs/list.h>
31 #else
32 #include <linux/crypto.h>
33 #include <linux/key.h>
34 #endif
35
36 #include <obd.h>
37 #include <obd_class.h>
38 #include <obd_support.h>
39 #include <lustre_net.h>
40 #include <lustre_import.h>
41 #include <lustre_dlm.h>
42 #include <lustre_sec.h>
43
44 #include "ptlrpc_internal.h"
45
46 /***********************************************
47  * policy registers                            *
48  ***********************************************/
49
50 static rwlock_t policy_lock = RW_LOCK_UNLOCKED;
51 static struct ptlrpc_sec_policy *policies[SPTLRPC_POLICY_MAX] = {
52         NULL,
53 };
54
55 int sptlrpc_register_policy(struct ptlrpc_sec_policy *policy)
56 {
57         __u32 number = policy->sp_policy;
58
59         LASSERT(policy->sp_name);
60         LASSERT(policy->sp_cops);
61         LASSERT(policy->sp_sops);
62
63         if (number >= SPTLRPC_POLICY_MAX)
64                 return -EINVAL;
65
66         write_lock(&policy_lock);
67         if (unlikely(policies[number])) {
68                 write_unlock(&policy_lock);
69                 return -EALREADY;
70         }
71         policies[number] = policy;
72         write_unlock(&policy_lock);
73
74         CDEBUG(D_SEC, "%s: registered\n", policy->sp_name);
75         return 0;
76 }
77 EXPORT_SYMBOL(sptlrpc_register_policy);
78
79 int sptlrpc_unregister_policy(struct ptlrpc_sec_policy *policy)
80 {
81         __u32 number = policy->sp_policy;
82
83         LASSERT(number < SPTLRPC_POLICY_MAX);
84
85         write_lock(&policy_lock);
86         if (unlikely(policies[number] == NULL)) {
87                 write_unlock(&policy_lock);
88                 CERROR("%s: already unregistered\n", policy->sp_name);
89                 return -EINVAL;
90         }
91
92         LASSERT(policies[number] == policy);
93         policies[number] = NULL;
94         write_unlock(&policy_lock);
95
96         CDEBUG(D_SEC, "%s: unregistered\n", policy->sp_name);
97         return 0;
98 }
99 EXPORT_SYMBOL(sptlrpc_unregister_policy);
100
101 static
102 struct ptlrpc_sec_policy * sptlrpc_flavor2policy(ptlrpc_sec_flavor_t flavor)
103 {
104 #ifdef CONFIG_KMOD
105         static DECLARE_MUTEX(load_mutex);
106 #endif
107         static atomic_t         loaded = ATOMIC_INIT(0);
108         struct                  ptlrpc_sec_policy *policy;
109         __u32                   number = SEC_FLAVOR_POLICY(flavor), flag = 0;
110
111         if (number >= SPTLRPC_POLICY_MAX)
112                 return NULL;
113
114 #ifdef CONFIG_KMOD
115 again:
116 #endif
117         read_lock(&policy_lock);
118         policy = policies[number];
119         if (policy && !try_module_get(policy->sp_owner))
120                 policy = NULL;
121         if (policy == NULL)
122                 flag = atomic_read(&loaded);
123         read_unlock(&policy_lock);
124
125 #ifdef CONFIG_KMOD
126         /* if failure, try to load gss module, once */
127         if (unlikely(policy == NULL) &&
128             flag == 0 &&
129             (number == SPTLRPC_POLICY_GSS ||
130              number == SPTLRPC_POLICY_GSS_PIPEFS)) {
131                 mutex_down(&load_mutex);
132                 if (atomic_read(&loaded) == 0) {
133                         if (request_module("ptlrpc_gss") != 0)
134                                 CERROR("Unable to load module ptlrpc_gss\n");
135                         else
136                                 CWARN("module ptlrpc_gss loaded\n");
137
138                         atomic_set(&loaded, 1);
139                 }
140                 mutex_up(&load_mutex);
141
142                 goto again;
143         }
144 #endif
145
146         return policy;
147 }
148
149 ptlrpc_sec_flavor_t sptlrpc_name2flavor(const char *name)
150 {
151         if (!strcmp(name, "null"))
152                 return SPTLRPC_FLVR_NULL;
153         if (!strcmp(name, "plain"))
154                 return SPTLRPC_FLVR_PLAIN;
155         if (!strcmp(name, "krb5"))
156                 return SPTLRPC_FLVR_KRB5;
157         if (!strcmp(name, "krb5i"))
158                 return SPTLRPC_FLVR_KRB5I;
159         if (!strcmp(name, "krb5p"))
160                 return SPTLRPC_FLVR_KRB5P;
161
162         return SPTLRPC_FLVR_INVALID;
163 }
164 EXPORT_SYMBOL(sptlrpc_name2flavor);
165
166 char *sptlrpc_flavor2name(ptlrpc_sec_flavor_t flavor)
167 {
168         switch (flavor) {
169         case SPTLRPC_FLVR_NULL:
170                 return "null";
171         case SPTLRPC_FLVR_PLAIN:
172                 return "plain";
173         case SPTLRPC_FLVR_KRB5:
174                 return "krb5";
175         case SPTLRPC_FLVR_KRB5I:
176                 return "krb5i";
177         case SPTLRPC_FLVR_KRB5P:
178                 return "krb5p";
179         default:
180                 CERROR("invalid flavor 0x%x(p%u,s%u,v%u)\n", flavor,
181                        SEC_FLAVOR_POLICY(flavor), SEC_FLAVOR_SUBPOLICY(flavor),
182                        SEC_FLAVOR_SVC(flavor));
183         }
184         return "UNKNOWN";
185 }
186 EXPORT_SYMBOL(sptlrpc_flavor2name);
187
188 /**************************************************
189  * client context APIs                            *
190  **************************************************/
191
192 static
193 struct ptlrpc_cli_ctx *get_my_ctx(struct ptlrpc_sec *sec)
194 {
195         struct vfs_cred vcred;
196         int create = 1, remove_dead = 1;
197
198         LASSERT(sec);
199         LASSERT(sec->ps_policy->sp_cops->lookup_ctx);
200
201         if (sec->ps_flags & (PTLRPC_SEC_FL_REVERSE | PTLRPC_SEC_FL_ROOTONLY)) {
202                 vcred.vc_uid = 0;
203                 vcred.vc_gid = 0;
204                 if (sec->ps_flags & PTLRPC_SEC_FL_REVERSE) {
205                         create = 0;
206                         remove_dead = 0;
207                 }
208         } else {
209                 vcred.vc_uid = cfs_current()->uid;
210                 vcred.vc_gid = cfs_current()->gid;
211         }
212
213         return sec->ps_policy->sp_cops->lookup_ctx(sec, &vcred,
214                                                    create, remove_dead);
215 }
216
217 struct ptlrpc_cli_ctx *sptlrpc_cli_ctx_get(struct ptlrpc_cli_ctx *ctx)
218 {
219         LASSERT(atomic_read(&ctx->cc_refcount) > 0);
220         atomic_inc(&ctx->cc_refcount);
221         return ctx;
222 }
223 EXPORT_SYMBOL(sptlrpc_cli_ctx_get);
224
225 void sptlrpc_cli_ctx_put(struct ptlrpc_cli_ctx *ctx, int sync)
226 {
227         struct ptlrpc_sec *sec = ctx->cc_sec;
228
229         LASSERT(sec);
230         LASSERT(atomic_read(&ctx->cc_refcount));
231
232         if (!atomic_dec_and_test(&ctx->cc_refcount))
233                 return;
234
235         sec->ps_policy->sp_cops->release_ctx(sec, ctx, sync);
236 }
237 EXPORT_SYMBOL(sptlrpc_cli_ctx_put);
238
239 /*
240  * expire the context immediately.
241  * the caller must hold at least 1 ref on the ctx.
242  */
243 void sptlrpc_cli_ctx_expire(struct ptlrpc_cli_ctx *ctx)
244 {
245         LASSERT(ctx->cc_ops->die);
246         ctx->cc_ops->die(ctx, 0);
247 }
248 EXPORT_SYMBOL(sptlrpc_cli_ctx_expire);
249
250 void sptlrpc_cli_ctx_wakeup(struct ptlrpc_cli_ctx *ctx)
251 {
252         struct ptlrpc_request *req, *next;
253
254         spin_lock(&ctx->cc_lock);
255         list_for_each_entry_safe(req, next, &ctx->cc_req_list, rq_ctx_chain) {
256                 list_del_init(&req->rq_ctx_chain);
257                 ptlrpc_wake_client_req(req);
258         }
259         spin_unlock(&ctx->cc_lock);
260 }
261 EXPORT_SYMBOL(sptlrpc_cli_ctx_wakeup);
262
263 int sptlrpc_cli_ctx_display(struct ptlrpc_cli_ctx *ctx, char *buf, int bufsize)
264 {
265         LASSERT(ctx->cc_ops);
266
267         if (ctx->cc_ops->display == NULL)
268                 return 0;
269
270         return ctx->cc_ops->display(ctx, buf, bufsize);
271 }
272
273 int sptlrpc_req_get_ctx(struct ptlrpc_request *req)
274 {
275         struct obd_import *imp = req->rq_import;
276         ENTRY;
277
278         LASSERT(!req->rq_cli_ctx);
279         LASSERT(imp);
280
281         if (imp->imp_sec == NULL) {
282                 CERROR("import %p (%s) with no sec pointer\n",
283                        imp, ptlrpc_import_state_name(imp->imp_state));
284                 RETURN(-EACCES);
285         }
286
287         req->rq_cli_ctx = get_my_ctx(imp->imp_sec);
288
289         if (!req->rq_cli_ctx) {
290                 CERROR("req %p: fail to get context\n", req);
291                 RETURN(-ENOMEM);
292         }
293
294         RETURN(0);
295 }
296
297 void sptlrpc_req_put_ctx(struct ptlrpc_request *req)
298 {
299         ENTRY;
300
301         LASSERT(req);
302         LASSERT(req->rq_cli_ctx);
303
304         /* request might be asked to release earlier while still
305          * in the context waiting list.
306          */
307         if (!list_empty(&req->rq_ctx_chain)) {
308                 spin_lock(&req->rq_cli_ctx->cc_lock);
309                 list_del_init(&req->rq_ctx_chain);
310                 spin_unlock(&req->rq_cli_ctx->cc_lock);
311         }
312
313         /* this could be called with spinlock hold, use async mode */
314         sptlrpc_cli_ctx_put(req->rq_cli_ctx, 0);
315         req->rq_cli_ctx = NULL;
316         EXIT;
317 }
318
319 /*
320  * request must have a context. if failed to get new context,
321  * just restore the old one
322  */
323 int sptlrpc_req_replace_dead_ctx(struct ptlrpc_request *req)
324 {
325         struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx;
326         int rc;
327         ENTRY;
328
329         LASSERT(ctx);
330         LASSERT(test_bit(PTLRPC_CTX_DEAD_BIT, &ctx->cc_flags));
331
332         /* make sure not on context waiting list */
333         spin_lock(&ctx->cc_lock);
334         list_del_init(&req->rq_ctx_chain);
335         spin_unlock(&ctx->cc_lock);
336
337         sptlrpc_cli_ctx_get(ctx);
338         sptlrpc_req_put_ctx(req);
339         rc = sptlrpc_req_get_ctx(req);
340         if (!rc) {
341                 LASSERT(req->rq_cli_ctx);
342                 sptlrpc_cli_ctx_put(ctx, 1);
343         } else {
344                 LASSERT(!req->rq_cli_ctx);
345                 req->rq_cli_ctx = ctx;
346         }
347         RETURN(rc);
348 }
349 EXPORT_SYMBOL(sptlrpc_req_replace_dead_ctx);
350
351 static
352 int ctx_check_refresh(struct ptlrpc_cli_ctx *ctx)
353 {
354         if (cli_ctx_is_refreshed(ctx))
355                 return 1;
356         return 0;
357 }
358
359 static
360 int ctx_refresh_timeout(void *data)
361 {
362         struct ptlrpc_request *req = data;
363         int rc;
364
365         /* conn_cnt is needed in expire_one_request */
366         lustre_msg_set_conn_cnt(req->rq_reqmsg, req->rq_import->imp_conn_cnt);
367
368         rc = ptlrpc_expire_one_request(req);
369         /* if we started recovery, we should mark this ctx dead; otherwise
370          * in case of lgssd died nobody would retire this ctx, following
371          * connecting will still find the same ctx thus cause deadlock.
372          * there's an assumption that expire time of the request should be
373          * later than the context refresh expire time.
374          */
375         if (rc == 0)
376                 req->rq_cli_ctx->cc_ops->die(req->rq_cli_ctx, 0);
377         return rc;
378 }
379
380 static
381 void ctx_refresh_interrupt(void *data)
382 {
383         /* do nothing */
384 }
385
386 static
387 void req_off_ctx_list(struct ptlrpc_request *req, struct ptlrpc_cli_ctx *ctx)
388 {
389         spin_lock(&ctx->cc_lock);
390         if (!list_empty(&req->rq_ctx_chain))
391                 list_del_init(&req->rq_ctx_chain);
392         spin_unlock(&ctx->cc_lock);
393 }
394
395 /*
396  * the status of context could be subject to be changed by other threads at any
397  * time. we allow this race. but once we return with 0, the caller will
398  * suppose it's uptodated and keep using it until the owning rpc is done.
399  *
400  * @timeout:
401  *    < 0  - don't wait
402  *    = 0  - wait until success or fatal error occur
403  *    > 0  - timeout value
404  *
405  * return 0 only if the context is uptodated.
406  */
407 int sptlrpc_req_refresh_ctx(struct ptlrpc_request *req, long timeout)
408 {
409         struct ptlrpc_cli_ctx  *ctx = req->rq_cli_ctx;
410         struct l_wait_info      lwi;
411         int                     rc;
412         ENTRY;
413
414         LASSERT(ctx);
415
416         /* skip reverse ctxs */
417         if (ctx->cc_sec->ps_flags & PTLRPC_SEC_FL_REVERSE)
418                 RETURN(0);
419
420         /* skip special ctxs */
421         if (cli_ctx_is_eternal(ctx) || req->rq_ctx_init || req->rq_ctx_fini)
422                 RETURN(0);
423
424         if (test_bit(PTLRPC_CTX_NEW_BIT, &ctx->cc_flags)) {
425                 LASSERT(ctx->cc_ops->refresh);
426                 ctx->cc_ops->refresh(ctx);
427         }
428         LASSERT(test_bit(PTLRPC_CTX_NEW_BIT, &ctx->cc_flags) == 0);
429
430 again:
431         if (unlikely(test_bit(PTLRPC_CTX_ERROR_BIT, &ctx->cc_flags))) {
432                 req->rq_err = 1;
433                 req_off_ctx_list(req, ctx);
434                 RETURN(-EPERM);
435         }
436
437         /* This is subtle. For resent message we have to keep original
438          * context to survive following situation:
439          *  1. the request sent to server
440          *  2. recovery was kick start
441          *  3. recovery finished, the request marked as resent
442          *  4. resend the request
443          *  5. old reply from server received (because xid is the same)
444          *  6. verify reply (has to be success)
445          *  7. new reply from server received, lnet drop it
446          *
447          * Note we can't simply change xid for resent request because
448          * server reply on it for reply reconstruction.
449          *
450          * Commonly the original context should be uptodate because we
451          * have a expiry nice time; And server will keep their half part
452          * context because we at least hold a ref of old context which
453          * prevent the context detroy RPC be sent. So server still can
454          * accept the request and finish RPC. Two cases:
455          *  1. If server side context has been trimed, a NO_CONTEXT will
456          *     be returned, gss_cli_ctx_verify/unseal will switch to new
457          *     context by force.
458          *  2. Current context never be refreshed, then we are fine: we
459          *     never really send request with old context before.
460          */
461         if (test_bit(PTLRPC_CTX_UPTODATE_BIT, &ctx->cc_flags) &&
462             unlikely(req->rq_reqmsg) &&
463             lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT) {
464                 req_off_ctx_list(req, ctx);
465                 RETURN(0);
466         }
467
468         if (unlikely(test_bit(PTLRPC_CTX_DEAD_BIT, &ctx->cc_flags))) {
469                 /* don't have to, but we don't want to release it too soon */
470                 sptlrpc_cli_ctx_get(ctx);
471
472                 rc = sptlrpc_req_replace_dead_ctx(req);
473                 if (rc) {
474                         LASSERT(ctx == req->rq_cli_ctx);
475                         CERROR("req %p: failed to replace dead ctx %p\n",
476                                 req, ctx);
477                         req->rq_err = 1;
478                         LASSERT(list_empty(&req->rq_ctx_chain));
479                         sptlrpc_cli_ctx_put(ctx, 1);
480                         RETURN(-ENOMEM);
481                 }
482
483                 /* FIXME
484                  * if ctx didn't really switch, might be cpu tight or sth,
485                  * we just relax a little bit.
486                  */
487                 if (ctx == req->rq_cli_ctx)
488                         schedule();
489
490                 CWARN("req %p: replace dead ctx %p(%u->%s) => %p\n",
491                       req, ctx, ctx->cc_vcred.vc_uid,
492                       sec2target_str(ctx->cc_sec), req->rq_cli_ctx);
493
494                 sptlrpc_cli_ctx_put(ctx, 1);
495                 ctx = req->rq_cli_ctx;
496                 LASSERT(list_empty(&req->rq_ctx_chain));
497
498                 goto again;
499         }
500
501         LASSERT(ctx->cc_ops->validate);
502         if (ctx->cc_ops->validate(ctx) == 0) {
503                 req_off_ctx_list(req, ctx);
504                 RETURN(0);
505         }
506
507         /* Now we're sure this context is during upcall, add myself into
508          * waiting list
509          */
510         spin_lock(&ctx->cc_lock);
511         if (list_empty(&req->rq_ctx_chain))
512                 list_add(&req->rq_ctx_chain, &ctx->cc_req_list);
513         spin_unlock(&ctx->cc_lock);
514
515         if (timeout < 0) {
516                 RETURN(-EWOULDBLOCK);
517         }
518
519         /* Clear any flags that may be present from previous sends */
520         LASSERT(req->rq_receiving_reply == 0);
521         spin_lock(&req->rq_lock);
522         req->rq_err = 0;
523         req->rq_timedout = 0;
524         req->rq_resend = 0;
525         req->rq_restart = 0;
526         spin_unlock(&req->rq_lock);
527
528         lwi = LWI_TIMEOUT_INTR(timeout == 0 ? LONG_MAX : timeout * HZ,
529                                ctx_refresh_timeout, ctx_refresh_interrupt, req);
530         rc = l_wait_event(req->rq_reply_waitq, ctx_check_refresh(ctx), &lwi);
531
532         /* five cases we are here:
533          * 1. successfully refreshed;
534          * 2. someone else mark this ctx dead by force;
535          * 3. interruptted;
536          * 4. timedout, and we don't want recover from the failure;
537          * 5. timedout, and waked up upon recovery finished;
538          */
539         if (!cli_ctx_is_refreshed(ctx)) {
540                 /* timed out or interruptted */
541                 req_off_ctx_list(req, ctx);
542
543                 LASSERT(rc != 0);
544                 RETURN(rc);
545         }
546
547         goto again;
548 }
549
550 void sptlrpc_req_set_flavor(struct ptlrpc_request *req, int opcode)
551 {
552         struct sec_flavor_config *conf;
553
554         LASSERT(req->rq_import);
555         LASSERT(req->rq_import->imp_sec);
556         LASSERT(req->rq_cli_ctx);
557         LASSERT(req->rq_cli_ctx->cc_sec);
558         LASSERT(req->rq_bulk_read == 0 || req->rq_bulk_write == 0);
559
560         /* special security flags accoding to opcode */
561         switch (opcode) {
562         case OST_READ:
563                 req->rq_bulk_read = 1;
564                 break;
565         case OST_WRITE:
566                 req->rq_bulk_write = 1;
567                 break;
568         case SEC_CTX_INIT:
569                 req->rq_ctx_init = 1;
570                 break;
571         case SEC_CTX_FINI:
572                 req->rq_ctx_fini = 1;
573                 break;
574         }
575
576         req->rq_sec_flavor = req->rq_cli_ctx->cc_sec->ps_flavor;
577
578         /* force SVC_NONE for context initiation rpc, SVC_AUTH for context
579          * destruction rpc
580          */
581         if (unlikely(req->rq_ctx_init)) {
582                 req->rq_sec_flavor = SEC_MAKE_RPC_FLAVOR(
583                                 SEC_FLAVOR_POLICY(req->rq_sec_flavor),
584                                 SEC_FLAVOR_SUBPOLICY(req->rq_sec_flavor),
585                                 SEC_FLAVOR_SVC(SPTLRPC_SVC_NONE));
586         } else if (unlikely(req->rq_ctx_fini)) {
587                 req->rq_sec_flavor = SEC_MAKE_RPC_FLAVOR(
588                                 SEC_FLAVOR_POLICY(req->rq_sec_flavor),
589                                 SEC_FLAVOR_SUBPOLICY(req->rq_sec_flavor),
590                                 SEC_FLAVOR_SVC(SPTLRPC_SVC_AUTH));
591         }
592
593         conf = &req->rq_import->imp_obd->u.cli.cl_sec_conf;
594
595         /* user descriptor flag, except ROOTONLY which don't need, and
596          * null security which can't
597          */
598         if ((conf->sfc_flags & PTLRPC_SEC_FL_ROOTONLY) == 0 &&
599             req->rq_sec_flavor != SPTLRPC_FLVR_NULL)
600                 req->rq_sec_flavor |= SEC_FLAVOR_FL_USER;
601
602         /* bulk security flag */
603         if ((req->rq_bulk_read || req->rq_bulk_write) &&
604             (conf->sfc_bulk_priv != BULK_PRIV_ALG_NULL ||
605              conf->sfc_bulk_csum != BULK_CSUM_ALG_NULL))
606                 req->rq_sec_flavor |= SEC_FLAVOR_FL_BULK;
607 }
608
609 void sptlrpc_request_out_callback(struct ptlrpc_request *req)
610 {
611         if (SEC_FLAVOR_SVC(req->rq_sec_flavor) != SPTLRPC_SVC_PRIV)
612                 return;
613
614         LASSERT(req->rq_clrbuf);
615         if (req->rq_pool || !req->rq_reqbuf)
616                 return;
617
618         OBD_FREE(req->rq_reqbuf, req->rq_reqbuf_len);
619         req->rq_reqbuf = NULL;
620         req->rq_reqbuf_len = 0;
621 }
622
623 /*
624  * check whether current user have valid context for an import or not.
625  * might repeatedly try in case of non-fatal errors.
626  * return 0 on success, < 0 on failure
627  */
628 int sptlrpc_import_check_ctx(struct obd_import *imp)
629 {
630         struct ptlrpc_cli_ctx *ctx;
631         struct ptlrpc_request *req = NULL;
632         int rc;
633         ENTRY;
634
635         might_sleep();
636
637         ctx = get_my_ctx(imp->imp_sec);
638         if (!ctx)
639                 RETURN(1);
640
641         if (cli_ctx_is_eternal(ctx) ||
642             ctx->cc_ops->validate(ctx) == 0) {
643                 sptlrpc_cli_ctx_put(ctx, 1);
644                 RETURN(0);
645         }
646
647         OBD_ALLOC_PTR(req);
648         if (!req)
649                 RETURN(-ENOMEM);
650
651         spin_lock_init(&req->rq_lock);
652         atomic_set(&req->rq_refcount, 10000);
653         INIT_LIST_HEAD(&req->rq_ctx_chain);
654         init_waitqueue_head(&req->rq_reply_waitq);
655         req->rq_import = imp;
656         req->rq_cli_ctx = ctx;
657
658         rc = sptlrpc_req_refresh_ctx(req, 0);
659         LASSERT(list_empty(&req->rq_ctx_chain));
660         sptlrpc_cli_ctx_put(req->rq_cli_ctx, 1);
661         OBD_FREE_PTR(req);
662
663         RETURN(rc);
664 }
665
666 int sptlrpc_cli_wrap_request(struct ptlrpc_request *req)
667 {
668         struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx;
669         int rc = 0;
670         ENTRY;
671
672         LASSERT(ctx);
673         LASSERT(ctx->cc_sec);
674         LASSERT(req->rq_reqbuf || req->rq_clrbuf);
675
676         /* we wrap bulk request here because now we can be sure
677          * the context is uptodate.
678          */
679         if (req->rq_bulk) {
680                 rc = sptlrpc_cli_wrap_bulk(req, req->rq_bulk);
681                 if (rc)
682                         RETURN(rc);
683         }
684
685         switch (SEC_FLAVOR_SVC(req->rq_sec_flavor)) {
686         case SPTLRPC_SVC_NONE:
687         case SPTLRPC_SVC_AUTH:
688                 LASSERT(ctx->cc_ops->sign);
689                 rc = ctx->cc_ops->sign(ctx, req);
690                 break;
691         case SPTLRPC_SVC_PRIV:
692                 LASSERT(ctx->cc_ops->seal);
693                 rc = ctx->cc_ops->seal(ctx, req);
694                 break;
695         default:
696                 LBUG();
697         }
698
699         if (rc == 0) {
700                 LASSERT(req->rq_reqdata_len);
701                 LASSERT(req->rq_reqdata_len % 8 == 0);
702                 LASSERT(req->rq_reqdata_len <= req->rq_reqbuf_len);
703         }
704
705         RETURN(rc);
706 }
707
708 /*
709  * rq_nob_received is the actual received data length
710  */
711 int sptlrpc_cli_unwrap_reply(struct ptlrpc_request *req)
712 {
713         struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx;
714         int rc;
715         ENTRY;
716
717         LASSERT(ctx);
718         LASSERT(ctx->cc_sec);
719         LASSERT(ctx->cc_ops);
720         LASSERT(req->rq_repbuf);
721
722         req->rq_repdata_len = req->rq_nob_received;
723
724         if (req->rq_nob_received < sizeof(struct lustre_msg)) {
725                 CERROR("replied data length %d too small\n",
726                        req->rq_nob_received);
727                 RETURN(-EPROTO);
728         }
729
730         if (req->rq_repbuf->lm_magic == LUSTRE_MSG_MAGIC_V1 ||
731             req->rq_repbuf->lm_magic == LUSTRE_MSG_MAGIC_V1_SWABBED) {
732                 /* it's must be null flavor, so our requets also should be
733                  * in null flavor */
734                 if (SEC_FLAVOR_POLICY(req->rq_sec_flavor) !=
735                     SPTLRPC_POLICY_NULL) {
736                         CERROR("request flavor is %x but reply with null\n",
737                                req->rq_sec_flavor);
738                         RETURN(-EPROTO);
739                 }
740         } else {
741                 /* v2 message... */
742                 ptlrpc_sec_flavor_t tmpf = req->rq_repbuf->lm_secflvr;
743
744                 if (req->rq_repbuf->lm_magic == LUSTRE_MSG_MAGIC_V2_SWABBED)
745                         __swab32s(&tmpf);
746
747                 if (SEC_FLAVOR_POLICY(tmpf) !=
748                     SEC_FLAVOR_POLICY(req->rq_sec_flavor)) {
749                         CERROR("request policy %u while reply with %d\n",
750                                SEC_FLAVOR_POLICY(req->rq_sec_flavor),
751                                SEC_FLAVOR_POLICY(tmpf));
752                         RETURN(-EPROTO);
753                 }
754
755                 if ((SEC_FLAVOR_POLICY(req->rq_sec_flavor) !=
756                      SPTLRPC_POLICY_NULL) &&
757                     lustre_unpack_msg(req->rq_repbuf, req->rq_nob_received))
758                         RETURN(-EPROTO);
759         }
760
761         switch (SEC_FLAVOR_SVC(req->rq_sec_flavor)) {
762         case SPTLRPC_SVC_NONE:
763         case SPTLRPC_SVC_AUTH:
764                 LASSERT(ctx->cc_ops->verify);
765                 rc = ctx->cc_ops->verify(ctx, req);
766                 break;
767         case SPTLRPC_SVC_PRIV:
768                 LASSERT(ctx->cc_ops->unseal);
769                 rc = ctx->cc_ops->unseal(ctx, req);
770                 break;
771         default:
772                 LBUG();
773         }
774
775         LASSERT(rc || req->rq_repmsg || req->rq_resend);
776         RETURN(rc);
777 }
778
779 /**************************************************
780  * client side high-level security APIs           *
781  **************************************************/
782
783 static
784 void sec_cop_destroy_sec(struct ptlrpc_sec *sec)
785 {
786         struct ptlrpc_sec_policy *policy = sec->ps_policy;
787
788         LASSERT(atomic_read(&sec->ps_refcount) == 0);
789         LASSERT(atomic_read(&sec->ps_busy) == 0);
790         LASSERT(policy->sp_cops->destroy_sec);
791
792         CWARN("%s@%p: being destroied\n", sec->ps_policy->sp_name, sec);
793
794         policy->sp_cops->destroy_sec(sec);
795         sptlrpc_policy_put(policy);
796 }
797
798 static
799 int sec_cop_flush_ctx_cache(struct ptlrpc_sec *sec, uid_t uid,
800                             int grace, int force)
801 {
802         struct ptlrpc_sec_policy *policy = sec->ps_policy;
803
804         LASSERT(policy->sp_cops);
805         LASSERT(policy->sp_cops->flush_ctx_cache);
806
807         return policy->sp_cops->flush_ctx_cache(sec, uid, grace, force);
808 }
809
810 void sptlrpc_sec_destroy(struct ptlrpc_sec *sec)
811 {
812         sec_cop_destroy_sec(sec);
813 }
814 EXPORT_SYMBOL(sptlrpc_sec_destroy);
815
816 /*
817  * let policy module to determine whether take refrence of
818  * import or not.
819  */
820 static
821 struct ptlrpc_sec * import_create_sec(struct obd_import *imp,
822                                       struct ptlrpc_svc_ctx *ctx,
823                                       __u32 flavor,
824                                       unsigned long flags)
825 {
826         struct ptlrpc_sec_policy *policy;
827         struct ptlrpc_sec *sec;
828         ENTRY;
829
830         flavor = SEC_FLAVOR_RPC(flavor);
831
832         if (ctx) {
833                 LASSERT(imp->imp_dlm_fake == 1);
834
835                 CDEBUG(D_SEC, "%s %s: reverse sec using flavor %s\n",
836                        imp->imp_obd->obd_type->typ_name,
837                        imp->imp_obd->obd_name,
838                        sptlrpc_flavor2name(flavor));
839
840                 policy = sptlrpc_policy_get(ctx->sc_policy);
841                 flags |= PTLRPC_SEC_FL_REVERSE | PTLRPC_SEC_FL_ROOTONLY;
842         } else {
843                 LASSERT(imp->imp_dlm_fake == 0);
844
845                 CDEBUG(D_SEC, "%s %s: select security flavor %s\n",
846                        imp->imp_obd->obd_type->typ_name,
847                        imp->imp_obd->obd_name,
848                        sptlrpc_flavor2name(flavor));
849
850                 policy = sptlrpc_flavor2policy(flavor);
851                 if (!policy) {
852                         CERROR("invalid flavor 0x%x\n", flavor);
853                         RETURN(NULL);
854                 }
855         }
856
857         sec = policy->sp_cops->create_sec(imp, ctx, flavor, flags);
858         if (sec) {
859                 atomic_inc(&sec->ps_refcount);
860
861                 /* take 1 busy count on behalf of sec itself,
862                  * balanced in sptlrpc_set_put()
863                  */
864                 atomic_inc(&sec->ps_busy);
865
866                 if (sec->ps_gc_interval && policy->sp_cops->gc_ctx)
867                         sptlrpc_gc_add_sec(sec);
868         } else
869                 sptlrpc_policy_put(policy);
870
871         RETURN(sec);
872 }
873
874 int sptlrpc_import_get_sec(struct obd_import *imp,
875                            struct ptlrpc_svc_ctx *ctx,
876                            __u32 flavor,
877                            unsigned long flags)
878 {
879         might_sleep();
880
881         /* old sec might be still there in reconnecting */
882         if (imp->imp_sec)
883                 return 0;
884
885         imp->imp_sec = import_create_sec(imp, ctx, flavor, flags);
886         if (!imp->imp_sec)
887                 return -EINVAL;
888
889         return 0;
890 }
891
892 void sptlrpc_import_put_sec(struct obd_import *imp)
893 {
894         struct ptlrpc_sec        *sec;
895         struct ptlrpc_sec_policy *policy;
896
897         might_sleep();
898
899         if (imp->imp_sec == NULL)
900                 return;
901
902         sec = imp->imp_sec;
903         policy = sec->ps_policy;
904
905         if (!atomic_dec_and_test(&sec->ps_refcount)) {
906                 sptlrpc_policy_put(policy);
907                 goto out;
908         }
909
910         sec_cop_flush_ctx_cache(sec, -1, 1, 1);
911         sptlrpc_gc_del_sec(sec);
912
913         if (atomic_dec_and_test(&sec->ps_busy))
914                 sec_cop_destroy_sec(sec);
915         else {
916                 CWARN("delay to destroy %s@%p: busy contexts\n",
917                       policy->sp_name, sec);
918         }
919
920 out:
921         imp->imp_sec = NULL;
922 }
923
924 void sptlrpc_import_flush_root_ctx(struct obd_import *imp)
925 {
926         if (imp == NULL || imp->imp_sec == NULL)
927                 return;
928
929         /* it's important to use grace mode, see explain in
930          * sptlrpc_req_refresh_ctx()
931          */
932         sec_cop_flush_ctx_cache(imp->imp_sec, 0, 1, 1);
933 }
934
935 void sptlrpc_import_flush_my_ctx(struct obd_import *imp)
936 {
937         if (imp == NULL || imp->imp_sec == NULL)
938                 return;
939
940         sec_cop_flush_ctx_cache(imp->imp_sec, cfs_current()->uid, 1, 1);
941 }
942 EXPORT_SYMBOL(sptlrpc_import_flush_my_ctx);
943
944 void sptlrpc_import_flush_all_ctx(struct obd_import *imp)
945 {
946         if (imp == NULL || imp->imp_sec == NULL)
947                 return;
948
949         sec_cop_flush_ctx_cache(imp->imp_sec, -1, 0, 1);
950 }
951 EXPORT_SYMBOL(sptlrpc_import_flush_all_ctx);
952
953 /*
954  * when complete successfully, req->rq_reqmsg should point to the
955  * right place.
956  */
957 int sptlrpc_cli_alloc_reqbuf(struct ptlrpc_request *req, int msgsize)
958 {
959         struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx;
960         struct ptlrpc_sec_policy *policy;
961         int rc;
962
963         LASSERT(ctx);
964         LASSERT(atomic_read(&ctx->cc_refcount));
965         LASSERT(ctx->cc_sec);
966         LASSERT(ctx->cc_sec->ps_policy);
967         LASSERT(req->rq_reqmsg == NULL);
968
969         policy = ctx->cc_sec->ps_policy;
970         rc = policy->sp_cops->alloc_reqbuf(ctx->cc_sec, req, msgsize);
971         if (!rc) {
972                 LASSERT(req->rq_reqmsg);
973                 LASSERT(req->rq_reqbuf || req->rq_clrbuf);
974
975                 /* zeroing preallocated buffer */
976                 if (req->rq_pool)
977                         memset(req->rq_reqmsg, 0, msgsize);
978         }
979
980         return rc;
981 }
982
983 void sptlrpc_cli_free_reqbuf(struct ptlrpc_request *req)
984 {
985         struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx;
986         struct ptlrpc_sec_policy *policy;
987
988         LASSERT(ctx);
989         LASSERT(atomic_read(&ctx->cc_refcount));
990         LASSERT(ctx->cc_sec);
991         LASSERT(ctx->cc_sec->ps_policy);
992         LASSERT(req->rq_reqbuf || req->rq_clrbuf);
993
994         policy = ctx->cc_sec->ps_policy;
995         policy->sp_cops->free_reqbuf(ctx->cc_sec, req);
996 }
997
998 /*
999  * NOTE caller must guarantee the buffer size is enough for the enlargement
1000  */
1001 void _sptlrpc_enlarge_msg_inplace(struct lustre_msg *msg,
1002                                   int segment, int newsize)
1003 {
1004         void   *src, *dst;
1005         int     oldsize, oldmsg_size, movesize;
1006
1007         LASSERT(segment < msg->lm_bufcount);
1008         LASSERT(msg->lm_buflens[segment] <= newsize);
1009
1010         if (msg->lm_buflens[segment] == newsize)
1011                 return;
1012
1013         /* nothing to do if we are enlarging the last segment */
1014         if (segment == msg->lm_bufcount - 1) {
1015                 msg->lm_buflens[segment] = newsize;
1016                 return;
1017         }
1018
1019         oldsize = msg->lm_buflens[segment];
1020
1021         src = lustre_msg_buf(msg, segment + 1, 0);
1022         msg->lm_buflens[segment] = newsize;
1023         dst = lustre_msg_buf(msg, segment + 1, 0);
1024         msg->lm_buflens[segment] = oldsize;
1025
1026         /* move from segment + 1 to end segment */
1027         LASSERT(msg->lm_magic == LUSTRE_MSG_MAGIC_V2);
1028         oldmsg_size = lustre_msg_size_v2(msg->lm_bufcount, msg->lm_buflens);
1029         movesize = oldmsg_size - ((unsigned long) src - (unsigned long) msg);
1030         LASSERT(movesize >= 0);
1031
1032         if (movesize)
1033                 memmove(dst, src, movesize);
1034
1035         /* note we don't clear the ares where old data live, not secret */
1036
1037         /* finally set new segment size */
1038         msg->lm_buflens[segment] = newsize;
1039 }
1040 EXPORT_SYMBOL(_sptlrpc_enlarge_msg_inplace);
1041
1042 /*
1043  * enlarge @segment of upper message req->rq_reqmsg to @newsize, all data
1044  * will be preserved after enlargement. this must be called after rq_reqmsg has
1045  * been intialized at least.
1046  *
1047  * caller's attention: upon return, rq_reqmsg and rq_reqlen might have
1048  * been changed.
1049  */
1050 int sptlrpc_cli_enlarge_reqbuf(struct ptlrpc_request *req,
1051                                int segment, int newsize)
1052 {
1053         struct ptlrpc_cli_ctx    *ctx = req->rq_cli_ctx;
1054         struct ptlrpc_sec_cops   *cops;
1055         struct lustre_msg        *msg = req->rq_reqmsg;
1056
1057         LASSERT(ctx);
1058         LASSERT(msg);
1059         LASSERT(msg->lm_bufcount > segment);
1060         LASSERT(msg->lm_buflens[segment] <= newsize);
1061
1062         if (msg->lm_buflens[segment] == newsize)
1063                 return 0;
1064
1065         cops = ctx->cc_sec->ps_policy->sp_cops;
1066         LASSERT(cops->enlarge_reqbuf);
1067         return cops->enlarge_reqbuf(ctx->cc_sec, req, segment, newsize);
1068 }
1069 EXPORT_SYMBOL(sptlrpc_cli_enlarge_reqbuf);
1070
1071 int sptlrpc_cli_alloc_repbuf(struct ptlrpc_request *req, int msgsize)
1072 {
1073         struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx;
1074         struct ptlrpc_sec_policy *policy;
1075         ENTRY;
1076
1077         LASSERT(ctx);
1078         LASSERT(atomic_read(&ctx->cc_refcount));
1079         LASSERT(ctx->cc_sec);
1080         LASSERT(ctx->cc_sec->ps_policy);
1081
1082         if (req->rq_repbuf)
1083                 RETURN(0);
1084
1085         policy = ctx->cc_sec->ps_policy;
1086         RETURN(policy->sp_cops->alloc_repbuf(ctx->cc_sec, req, msgsize));
1087 }
1088
1089 void sptlrpc_cli_free_repbuf(struct ptlrpc_request *req)
1090 {
1091         struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx;
1092         struct ptlrpc_sec_policy *policy;
1093         ENTRY;
1094
1095         LASSERT(ctx);
1096         LASSERT(atomic_read(&ctx->cc_refcount));
1097         LASSERT(ctx->cc_sec);
1098         LASSERT(ctx->cc_sec->ps_policy);
1099         LASSERT(req->rq_repbuf);
1100
1101         policy = ctx->cc_sec->ps_policy;
1102         policy->sp_cops->free_repbuf(ctx->cc_sec, req);
1103         EXIT;
1104 }
1105
1106 int sptlrpc_cli_install_rvs_ctx(struct obd_import *imp,
1107                                 struct ptlrpc_cli_ctx *ctx)
1108 {
1109         struct ptlrpc_sec_policy *policy = ctx->cc_sec->ps_policy;
1110
1111         if (!policy->sp_cops->install_rctx)
1112                 return 0;
1113         return policy->sp_cops->install_rctx(imp, ctx->cc_sec, ctx);
1114 }
1115
1116 int sptlrpc_svc_install_rvs_ctx(struct obd_import *imp,
1117                                 struct ptlrpc_svc_ctx *ctx)
1118 {
1119         struct ptlrpc_sec_policy *policy = ctx->sc_policy;
1120
1121         if (!policy->sp_sops->install_rctx)
1122                 return 0;
1123         return policy->sp_sops->install_rctx(imp, ctx);
1124 }
1125
1126 /****************************************
1127  * server side security                 *
1128  ****************************************/
1129
1130 int sptlrpc_svc_unwrap_request(struct ptlrpc_request *req)
1131 {
1132         struct ptlrpc_sec_policy *policy;
1133         struct lustre_msg *msg = req->rq_reqbuf;
1134         int rc;
1135         ENTRY;
1136
1137         LASSERT(msg);
1138         LASSERT(req->rq_reqmsg == NULL);
1139         LASSERT(req->rq_repmsg == NULL);
1140
1141         /* 
1142          * in any case we avoid to call unpack_msg() for request of null flavor
1143          * which will later be done by ptlrpc_server_handle_request().
1144          */
1145         if (req->rq_reqdata_len < sizeof(struct lustre_msg)) {
1146                 CERROR("request size %d too small\n", req->rq_reqdata_len);
1147                 RETURN(SECSVC_DROP);
1148         }
1149
1150         if (msg->lm_magic == LUSTRE_MSG_MAGIC_V1 ||
1151             msg->lm_magic == LUSTRE_MSG_MAGIC_V1_SWABBED) {
1152                 req->rq_sec_flavor = SPTLRPC_FLVR_NULL;
1153         } else {
1154                 req->rq_sec_flavor = msg->lm_secflvr;
1155
1156                 if (msg->lm_magic == LUSTRE_MSG_MAGIC_V2_SWABBED)
1157                         __swab32s(&req->rq_sec_flavor);
1158
1159                 if ((SEC_FLAVOR_POLICY(req->rq_sec_flavor) !=
1160                      SPTLRPC_POLICY_NULL) &&
1161                     lustre_unpack_msg(msg, req->rq_reqdata_len))
1162                         RETURN(SECSVC_DROP);
1163         }
1164
1165         policy = sptlrpc_flavor2policy(req->rq_sec_flavor);
1166         if (!policy) {
1167                 CERROR("unsupported security flavor %x\n", req->rq_sec_flavor);
1168                 RETURN(SECSVC_DROP);
1169         }
1170
1171         LASSERT(policy->sp_sops->accept);
1172         rc = policy->sp_sops->accept(req);
1173
1174         LASSERT(req->rq_reqmsg || rc != SECSVC_OK);
1175         sptlrpc_policy_put(policy);
1176
1177         /* FIXME move to proper place */
1178         if (rc == SECSVC_OK) {
1179                 __u32 opc = lustre_msg_get_opc(req->rq_reqmsg);
1180
1181                 if (opc == OST_WRITE)
1182                         req->rq_bulk_write = 1;
1183                 else if (opc == OST_READ)
1184                         req->rq_bulk_read = 1;
1185         }
1186
1187         LASSERT(req->rq_svc_ctx || rc == SECSVC_DROP);
1188         RETURN(rc);
1189 }
1190
1191 int sptlrpc_svc_alloc_rs(struct ptlrpc_request *req,
1192                          int msglen)
1193 {
1194         struct ptlrpc_sec_policy *policy;
1195         struct ptlrpc_reply_state *rs;
1196         int rc;
1197         ENTRY;
1198
1199         LASSERT(req->rq_svc_ctx);
1200         LASSERT(req->rq_svc_ctx->sc_policy);
1201
1202         policy = req->rq_svc_ctx->sc_policy;
1203         LASSERT(policy->sp_sops->alloc_rs);
1204
1205         rc = policy->sp_sops->alloc_rs(req, msglen);
1206         if (unlikely(rc == -ENOMEM)) {
1207                 /* failed alloc, try emergency pool */
1208                 rs = lustre_get_emerg_rs(req->rq_rqbd->rqbd_service);
1209                 if (rs == NULL)
1210                         RETURN(-ENOMEM);
1211
1212                 req->rq_reply_state = rs;
1213                 rc = policy->sp_sops->alloc_rs(req, msglen);
1214                 if (rc) {
1215                         lustre_put_emerg_rs(rs);
1216                         req->rq_reply_state = NULL;
1217                 }
1218         }
1219
1220         LASSERT(rc != 0 ||
1221                 (req->rq_reply_state && req->rq_reply_state->rs_msg));
1222
1223         RETURN(rc);
1224 }
1225
1226 int sptlrpc_svc_wrap_reply(struct ptlrpc_request *req)
1227 {
1228         struct ptlrpc_sec_policy *policy;
1229         int rc;
1230         ENTRY;
1231
1232         LASSERT(req->rq_svc_ctx);
1233         LASSERT(req->rq_svc_ctx->sc_policy);
1234
1235         policy = req->rq_svc_ctx->sc_policy;
1236         LASSERT(policy->sp_sops->authorize);
1237
1238         rc = policy->sp_sops->authorize(req);
1239         LASSERT(rc || req->rq_reply_state->rs_repdata_len);
1240
1241         RETURN(rc);
1242 }
1243
1244 void sptlrpc_svc_free_rs(struct ptlrpc_reply_state *rs)
1245 {
1246         struct ptlrpc_sec_policy *policy;
1247         unsigned int prealloc;
1248         ENTRY;
1249
1250         LASSERT(rs->rs_svc_ctx);
1251         LASSERT(rs->rs_svc_ctx->sc_policy);
1252
1253         policy = rs->rs_svc_ctx->sc_policy;
1254         LASSERT(policy->sp_sops->free_rs);
1255
1256         prealloc = rs->rs_prealloc;
1257         policy->sp_sops->free_rs(rs);
1258
1259         if (prealloc)
1260                 lustre_put_emerg_rs(rs);
1261         EXIT;
1262 }
1263
1264 void sptlrpc_svc_ctx_addref(struct ptlrpc_request *req)
1265 {
1266         struct ptlrpc_svc_ctx *ctx = req->rq_svc_ctx;
1267
1268         if (ctx == NULL)
1269                 return;
1270
1271         LASSERT(atomic_read(&ctx->sc_refcount) > 0);
1272         atomic_inc(&ctx->sc_refcount);
1273 }
1274
1275 void sptlrpc_svc_ctx_decref(struct ptlrpc_request *req)
1276 {
1277         struct ptlrpc_svc_ctx *ctx = req->rq_svc_ctx;
1278
1279         if (ctx == NULL)
1280                 return;
1281
1282         LASSERT(atomic_read(&ctx->sc_refcount) > 0);
1283         if (atomic_dec_and_test(&ctx->sc_refcount)) {
1284                 if (ctx->sc_policy->sp_sops->free_ctx)
1285                         ctx->sc_policy->sp_sops->free_ctx(ctx);
1286         }
1287         req->rq_svc_ctx = NULL;
1288 }
1289
1290 void sptlrpc_svc_ctx_invalidate(struct ptlrpc_request *req)
1291 {
1292         struct ptlrpc_svc_ctx *ctx = req->rq_svc_ctx;
1293
1294         if (ctx == NULL)
1295                 return;
1296
1297         LASSERT(atomic_read(&ctx->sc_refcount) > 0);
1298         if (ctx->sc_policy->sp_sops->invalidate_ctx)
1299                 ctx->sc_policy->sp_sops->invalidate_ctx(ctx);
1300 }
1301 EXPORT_SYMBOL(sptlrpc_svc_ctx_invalidate);
1302
1303 /****************************************
1304  * bulk security                        *
1305  ****************************************/
1306
1307 int sptlrpc_cli_wrap_bulk(struct ptlrpc_request *req,
1308                           struct ptlrpc_bulk_desc *desc)
1309 {
1310         struct ptlrpc_cli_ctx *ctx;
1311
1312         if (!SEC_FLAVOR_HAS_BULK(req->rq_sec_flavor))
1313                 return 0;
1314
1315         LASSERT(req->rq_bulk_read || req->rq_bulk_write);
1316
1317         ctx = req->rq_cli_ctx;
1318         if (ctx->cc_ops->wrap_bulk)
1319                 return ctx->cc_ops->wrap_bulk(ctx, req, desc);
1320         return 0;
1321 }
1322 EXPORT_SYMBOL(sptlrpc_cli_wrap_bulk);
1323
1324 static
1325 void pga_to_bulk_desc(int nob, obd_count pg_count, struct brw_page **pga,
1326                       struct ptlrpc_bulk_desc *desc)
1327 {
1328         int i;
1329
1330         LASSERT(pga);
1331         LASSERT(*pga);
1332
1333         for (i = 0; i < pg_count && nob > 0; i++) {
1334 #ifdef __KERNEL__
1335                 desc->bd_iov[i].kiov_page = pga[i]->pg;
1336                 desc->bd_iov[i].kiov_len = pga[i]->count > nob ?
1337                                            nob : pga[i]->count;
1338                 desc->bd_iov[i].kiov_offset = pga[i]->off & ~CFS_PAGE_MASK;
1339 #else
1340 #warning FIXME for liblustre!
1341                 desc->bd_iov[i].iov_base = pga[i]->pg->addr;
1342                 desc->bd_iov[i].iov_len = pga[i]->count > nob ?
1343                                            nob : pga[i]->count;
1344 #endif
1345
1346                 desc->bd_iov_count++;
1347                 nob -= pga[i]->count;
1348         }
1349 }
1350
1351 int sptlrpc_cli_unwrap_bulk_read(struct ptlrpc_request *req,
1352                                  int nob, obd_count pg_count,
1353                                  struct brw_page **pga)
1354 {
1355         struct ptlrpc_bulk_desc *desc;
1356         struct ptlrpc_cli_ctx *ctx;
1357         int rc = 0;
1358
1359         if (!SEC_FLAVOR_HAS_BULK(req->rq_sec_flavor))
1360                 return 0;
1361
1362         LASSERT(req->rq_bulk_read && !req->rq_bulk_write);
1363
1364         OBD_ALLOC(desc, offsetof(struct ptlrpc_bulk_desc, bd_iov[pg_count]));
1365         if (desc == NULL) {
1366                 CERROR("out of memory, can't verify bulk read data\n");
1367                 return -ENOMEM;
1368         }
1369
1370         pga_to_bulk_desc(nob, pg_count, pga, desc);
1371
1372         ctx = req->rq_cli_ctx;
1373         if (ctx->cc_ops->unwrap_bulk)
1374                 rc = ctx->cc_ops->unwrap_bulk(ctx, req, desc);
1375
1376         OBD_FREE(desc, offsetof(struct ptlrpc_bulk_desc, bd_iov[pg_count]));
1377
1378         return rc;
1379 }
1380 EXPORT_SYMBOL(sptlrpc_cli_unwrap_bulk_read);
1381
1382 int sptlrpc_cli_unwrap_bulk_write(struct ptlrpc_request *req,
1383                                   struct ptlrpc_bulk_desc *desc)
1384 {
1385         struct ptlrpc_cli_ctx *ctx;
1386
1387         if (!SEC_FLAVOR_HAS_BULK(req->rq_sec_flavor))
1388                 return 0;
1389
1390         LASSERT(!req->rq_bulk_read && req->rq_bulk_write);
1391
1392         ctx = req->rq_cli_ctx;
1393         if (ctx->cc_ops->unwrap_bulk)
1394                 return ctx->cc_ops->unwrap_bulk(ctx, req, desc);
1395
1396         return 0;
1397 }
1398 EXPORT_SYMBOL(sptlrpc_cli_unwrap_bulk_write);
1399
1400 int sptlrpc_svc_wrap_bulk(struct ptlrpc_request *req,
1401                           struct ptlrpc_bulk_desc *desc)
1402 {
1403         struct ptlrpc_svc_ctx *ctx;
1404
1405         if (!SEC_FLAVOR_HAS_BULK(req->rq_sec_flavor))
1406                 return 0;
1407
1408         LASSERT(req->rq_bulk_read || req->rq_bulk_write);
1409
1410         ctx = req->rq_svc_ctx;
1411         if (ctx->sc_policy->sp_sops->wrap_bulk)
1412                 return ctx->sc_policy->sp_sops->wrap_bulk(req, desc);
1413
1414         return 0;
1415 }
1416 EXPORT_SYMBOL(sptlrpc_svc_wrap_bulk);
1417
1418 int sptlrpc_svc_unwrap_bulk(struct ptlrpc_request *req,
1419                             struct ptlrpc_bulk_desc *desc)
1420 {
1421         struct ptlrpc_svc_ctx *ctx;
1422
1423         if (!SEC_FLAVOR_HAS_BULK(req->rq_sec_flavor))
1424                 return 0;
1425
1426         LASSERT(req->rq_bulk_read || req->rq_bulk_write);
1427
1428         ctx = req->rq_svc_ctx;
1429         if (ctx->sc_policy->sp_sops->unwrap_bulk);
1430                 return ctx->sc_policy->sp_sops->unwrap_bulk(req, desc);
1431
1432         return 0;
1433 }
1434 EXPORT_SYMBOL(sptlrpc_svc_unwrap_bulk);
1435
1436
1437 /****************************************
1438  * user descriptor helpers              *
1439  ****************************************/
1440
1441 int sptlrpc_current_user_desc_size(void)
1442 {
1443         int ngroups;
1444
1445 #ifdef __KERNEL__
1446         ngroups = current_ngroups;
1447
1448         if (ngroups > LUSTRE_MAX_GROUPS)
1449                 ngroups = LUSTRE_MAX_GROUPS;
1450 #else
1451         ngroups = 0;
1452 #endif
1453         return sptlrpc_user_desc_size(ngroups);
1454 }
1455 EXPORT_SYMBOL(sptlrpc_current_user_desc_size);
1456
1457 int sptlrpc_pack_user_desc(struct lustre_msg *msg, int offset)
1458 {
1459         struct ptlrpc_user_desc *pud;
1460
1461         pud = lustre_msg_buf(msg, offset, 0);
1462
1463         pud->pud_uid = cfs_current()->uid;
1464         pud->pud_gid = cfs_current()->gid;
1465         pud->pud_fsuid = cfs_current()->fsuid;
1466         pud->pud_fsgid = cfs_current()->fsgid;
1467         pud->pud_cap = cfs_current()->cap_effective;
1468         pud->pud_ngroups = (msg->lm_buflens[offset] - sizeof(*pud)) / 4;
1469
1470 #ifdef __KERNEL__
1471         task_lock(current);
1472         if (pud->pud_ngroups > current_ngroups)
1473                 pud->pud_ngroups = current_ngroups;
1474         memcpy(pud->pud_groups, cfs_current()->group_info->blocks[0],
1475                pud->pud_ngroups * sizeof(__u32));
1476         task_unlock(current);
1477 #endif
1478
1479         return 0;
1480 }
1481 EXPORT_SYMBOL(sptlrpc_pack_user_desc);
1482
1483 int sptlrpc_unpack_user_desc(struct lustre_msg *msg, int offset)
1484 {
1485         struct ptlrpc_user_desc *pud;
1486         int                      i;
1487
1488         pud = lustre_msg_buf(msg, offset, sizeof(*pud));
1489         if (!pud)
1490                 return -EINVAL;
1491
1492         if (lustre_msg_swabbed(msg)) {
1493                 __swab32s(&pud->pud_uid);
1494                 __swab32s(&pud->pud_gid);
1495                 __swab32s(&pud->pud_fsuid);
1496                 __swab32s(&pud->pud_fsgid);
1497                 __swab32s(&pud->pud_cap);
1498                 __swab32s(&pud->pud_ngroups);
1499         }
1500
1501         if (pud->pud_ngroups > LUSTRE_MAX_GROUPS) {
1502                 CERROR("%u groups is too large\n", pud->pud_ngroups);
1503                 return -EINVAL;
1504         }
1505
1506         if (sizeof(*pud) + pud->pud_ngroups * sizeof(__u32) >
1507             msg->lm_buflens[offset]) {
1508                 CERROR("%u groups are claimed but bufsize only %u\n",
1509                        pud->pud_ngroups, msg->lm_buflens[offset]);
1510                 return -EINVAL;
1511         }
1512
1513         if (lustre_msg_swabbed(msg)) {
1514                 for (i = 0; i < pud->pud_ngroups; i++)
1515                         __swab32s(&pud->pud_groups[i]);
1516         }
1517
1518         return 0;
1519 }
1520 EXPORT_SYMBOL(sptlrpc_unpack_user_desc);
1521
1522 /****************************************
1523  * user supplied flavor string parsing  *
1524  ****************************************/
1525
1526 static
1527 int get_default_flavor(enum lustre_part to_part, struct sec_flavor_config *conf)
1528 {
1529         conf->sfc_bulk_priv = BULK_PRIV_ALG_NULL;
1530         conf->sfc_bulk_csum = BULK_CSUM_ALG_NULL;
1531         conf->sfc_flags = 0;
1532
1533         switch (to_part) {
1534         case LUSTRE_MDT:
1535                 conf->sfc_rpc_flavor = SPTLRPC_FLVR_PLAIN;
1536                 return 0;
1537         case LUSTRE_OST:
1538                 conf->sfc_rpc_flavor = SPTLRPC_FLVR_NULL;
1539                 return 0;
1540         default:
1541                 CERROR("Unknown to lustre part %d, apply defaults\n", to_part);
1542                 conf->sfc_rpc_flavor = SPTLRPC_FLVR_NULL;
1543                 return -EINVAL;
1544         }
1545 }
1546
1547 static
1548 void get_flavor_by_rpc(__u32 rpc_flavor, struct sec_flavor_config *conf)
1549 {
1550         conf->sfc_rpc_flavor = rpc_flavor;
1551         conf->sfc_bulk_priv = BULK_PRIV_ALG_NULL;
1552         conf->sfc_bulk_csum = BULK_CSUM_ALG_NULL;
1553         conf->sfc_flags = 0;
1554
1555         switch (rpc_flavor) {
1556         case SPTLRPC_FLVR_NULL:
1557         case SPTLRPC_FLVR_PLAIN:
1558                 break;
1559         case SPTLRPC_FLVR_KRB5P:
1560                 conf->sfc_bulk_priv = BULK_PRIV_ALG_ARC4;
1561                 /* fall through */
1562         case SPTLRPC_FLVR_KRB5I:
1563                 conf->sfc_bulk_csum = BULK_CSUM_ALG_SHA1;
1564                 break;
1565         default:
1566                 LBUG();
1567         }
1568 }
1569
1570 static
1571 void get_flavor_by_rpc_bulk(__u32 rpc_flavor, int bulk_priv,
1572                             struct sec_flavor_config *conf)
1573 {
1574         if (bulk_priv)
1575                 conf->sfc_bulk_priv = BULK_PRIV_ALG_ARC4;
1576         else
1577                 conf->sfc_bulk_priv = BULK_PRIV_ALG_NULL;
1578
1579         switch (rpc_flavor) {
1580         case SPTLRPC_FLVR_PLAIN:
1581                 conf->sfc_bulk_csum = BULK_CSUM_ALG_MD5;
1582                 break;
1583         case SPTLRPC_FLVR_KRB5I:
1584         case SPTLRPC_FLVR_KRB5P:
1585                 conf->sfc_bulk_csum = BULK_CSUM_ALG_SHA1;
1586                 break;
1587         default:
1588                 LBUG();
1589         }
1590 }
1591
1592 static __u32 __flavors[] = {
1593         SPTLRPC_FLVR_NULL,
1594         SPTLRPC_FLVR_PLAIN,
1595         SPTLRPC_FLVR_KRB5I,
1596         SPTLRPC_FLVR_KRB5P,
1597 };
1598
1599 #define __nflavors      (sizeof(__flavors)/sizeof(__u32))
1600
1601 /*
1602  * flavor string format: rpc[-bulk{n|i|p}[:cksum/enc]]
1603  * for examples:
1604  *  null
1605  *  plain-bulki
1606  *  krb5p-bulkn
1607  *  krb5i-bulkp
1608  *  krb5i-bulkp:sha512/arc4
1609  */
1610 int sptlrpc_parse_flavor(enum lustre_part from_part, enum lustre_part to_part,
1611                          char *str, struct sec_flavor_config *conf)
1612 {
1613         char   *f, *bulk, *alg, *enc;
1614         char    buf[64];
1615         int     i, bulk_priv;
1616         ENTRY;
1617
1618         if (str == NULL) {
1619                 if (get_default_flavor(to_part, conf))
1620                         return -EINVAL;
1621                 goto set_flags;
1622         }
1623
1624         for (i = 0; i < __nflavors; i++) {
1625                 f = sptlrpc_flavor2name(__flavors[i]);
1626                 if (strncmp(str, f, strlen(f)) == 0)
1627                         break;
1628         }
1629
1630         if (i >= __nflavors)
1631                 GOTO(invalid, -EINVAL);
1632
1633         /* prepare local buffer thus we can modify it as we want */
1634         strncpy(buf, str, 64);
1635         buf[64 - 1] = '\0';
1636
1637         /* find bulk string */
1638         bulk = strchr(buf, '-');
1639         if (bulk)
1640                 *bulk++ = '\0';
1641
1642         /* now the first part must equal to rpc flavor name */
1643         if (strcmp(buf, f) != 0)
1644                 GOTO(invalid, -EINVAL);
1645
1646         get_flavor_by_rpc(__flavors[i], conf);
1647
1648         if (bulk == NULL)
1649                 goto set_flags;
1650
1651         /* null flavor should not have any suffix */
1652         if (__flavors[i] == SPTLRPC_FLVR_NULL)
1653                 GOTO(invalid, -EINVAL);
1654
1655         /* find bulk algorithm string */
1656         alg = strchr(bulk, ':');
1657         if (alg)
1658                 *alg++ = '\0';
1659
1660         /* verify bulk section */
1661         if (strcmp(bulk, "bulkn") == 0) {
1662                 conf->sfc_bulk_csum = BULK_CSUM_ALG_NULL;
1663                 conf->sfc_bulk_priv = BULK_PRIV_ALG_NULL;
1664                 goto set_flags;
1665         }
1666
1667         if (strcmp(bulk, "bulki") == 0)
1668                 bulk_priv = 0;
1669         else if (strcmp(bulk, "bulkp") == 0)
1670                 bulk_priv = 1;
1671         else
1672                 GOTO(invalid, -EINVAL);
1673
1674         /* plain policy dosen't support bulk encryption */
1675         if (bulk_priv && __flavors[i] == SPTLRPC_FLVR_PLAIN)
1676                 GOTO(invalid, -EINVAL);
1677
1678         get_flavor_by_rpc_bulk(__flavors[i], bulk_priv, conf);
1679
1680         if (alg == NULL)
1681                 goto set_flags;
1682
1683         /* find encryption algorithm string */
1684         enc = strchr(alg, '/');
1685         if (enc)
1686                 *enc++ = '\0';
1687
1688         /* bulk combination sanity check */
1689         if ((bulk_priv && enc == NULL) || (bulk_priv == 0 && enc))
1690                 GOTO(invalid, -EINVAL);
1691
1692         /* checksum algorithm */
1693         for (i = 0; i < BULK_CSUM_ALG_MAX; i++) {
1694                 if (strcmp(alg, sptlrpc_bulk_csum_alg2name(i)) == 0) {
1695                         conf->sfc_bulk_csum = i;
1696                         break;
1697                 }
1698         }
1699         if (i >= BULK_CSUM_ALG_MAX)
1700                 GOTO(invalid, -EINVAL);
1701
1702         /* privacy algorithm */
1703         if (enc) {
1704                 if (strcmp(enc, "arc4") != 0)
1705                         GOTO(invalid, -EINVAL);
1706                 conf->sfc_bulk_priv = BULK_PRIV_ALG_ARC4;
1707         }
1708
1709 set_flags:
1710         /* * set ROOTONLY flag:
1711          *   - to OST
1712          *   - from MDT to MDT
1713          * * set BULK flag for:
1714          *   - from CLI to OST
1715          */
1716         if (to_part == LUSTRE_OST ||
1717             (from_part == LUSTRE_MDT && to_part == LUSTRE_MDT))
1718                 conf->sfc_flags |= PTLRPC_SEC_FL_ROOTONLY;
1719         if (from_part == LUSTRE_CLI && to_part == LUSTRE_OST)
1720                 conf->sfc_flags |= PTLRPC_SEC_FL_BULK;
1721
1722 #ifdef __BIG_ENDIAN
1723         __swab32s(&conf->sfc_rpc_flavor);
1724         __swab32s(&conf->sfc_bulk_csum);
1725         __swab32s(&conf->sfc_bulk_priv);
1726         __swab32s(&conf->sfc_flags);
1727 #endif
1728         return 0;
1729 invalid:
1730         CERROR("invalid flavor string: %s\n", str);
1731         return -EINVAL;
1732 }
1733 EXPORT_SYMBOL(sptlrpc_parse_flavor);
1734
1735 /****************************************
1736  * misc helpers                         *
1737  ****************************************/
1738
1739 const char * sec2target_str(struct ptlrpc_sec *sec)
1740 {
1741         if (!sec || !sec->ps_import || !sec->ps_import->imp_obd)
1742                 return "*";
1743         if (sec->ps_flags & PTLRPC_SEC_FL_REVERSE)
1744                 return "c";
1745         return obd_uuid2str(&sec->ps_import->imp_obd->u.cli.cl_target_uuid);
1746 }
1747 EXPORT_SYMBOL(sec2target_str);
1748
1749 /****************************************
1750  * initialize/finalize                  *
1751  ****************************************/
1752
1753 int __init sptlrpc_init(void)
1754 {
1755         int rc;
1756
1757         rc = sptlrpc_gc_start_thread();
1758         if (rc)
1759                 goto out;
1760
1761         rc = sptlrpc_enc_pool_init();
1762         if (rc)
1763                 goto out_gc;
1764
1765         rc = sptlrpc_null_init();
1766         if (rc)
1767                 goto out_pool;
1768
1769         rc = sptlrpc_plain_init();
1770         if (rc)
1771                 goto out_null;
1772
1773         rc = sptlrpc_lproc_init();
1774         if (rc)
1775                 goto out_plain;
1776
1777         return 0;
1778
1779 out_plain:
1780         sptlrpc_plain_fini();
1781 out_null:
1782         sptlrpc_null_fini();
1783 out_pool:
1784         sptlrpc_enc_pool_fini();
1785 out_gc:
1786         sptlrpc_gc_stop_thread();
1787 out:
1788         return rc;
1789 }
1790
1791 void __exit sptlrpc_fini(void)
1792 {
1793         sptlrpc_lproc_fini();
1794         sptlrpc_plain_fini();
1795         sptlrpc_null_fini();
1796         sptlrpc_enc_pool_fini();
1797         sptlrpc_gc_stop_thread();
1798 }