Whamcloud - gitweb
LU-6496 ptlrpc: Fix wrong code indentation in plain_authorize
[fs/lustre-release.git] / lustre / ptlrpc / sec.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2011, 2014, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lustre/ptlrpc/sec.c
37  *
38  * Author: Eric Mei <ericm@clusterfs.com>
39  */
40
41 #define DEBUG_SUBSYSTEM S_SEC
42
43 #include <linux/user_namespace.h>
44 #ifdef HAVE_UIDGID_HEADER
45 # include <linux/uidgid.h>
46 #endif
47 #include <linux/crypto.h>
48 #include <linux/key.h>
49
50 #include <libcfs/libcfs.h>
51 #include <obd.h>
52 #include <obd_class.h>
53 #include <obd_support.h>
54 #include <lustre_net.h>
55 #include <lustre_import.h>
56 #include <lustre_dlm.h>
57 #include <lustre_sec.h>
58
59 #include "ptlrpc_internal.h"
60
61 /***********************************************
62  * policy registers                            *
63  ***********************************************/
64
65 static rwlock_t policy_lock;
66 static struct ptlrpc_sec_policy *policies[SPTLRPC_POLICY_MAX] = {
67         NULL,
68 };
69
70 int sptlrpc_register_policy(struct ptlrpc_sec_policy *policy)
71 {
72         __u16 number = policy->sp_policy;
73
74         LASSERT(policy->sp_name);
75         LASSERT(policy->sp_cops);
76         LASSERT(policy->sp_sops);
77
78         if (number >= SPTLRPC_POLICY_MAX)
79                 return -EINVAL;
80
81         write_lock(&policy_lock);
82         if (unlikely(policies[number])) {
83                 write_unlock(&policy_lock);
84                 return -EALREADY;
85         }
86         policies[number] = policy;
87         write_unlock(&policy_lock);
88
89         CDEBUG(D_SEC, "%s: registered\n", policy->sp_name);
90         return 0;
91 }
92 EXPORT_SYMBOL(sptlrpc_register_policy);
93
94 int sptlrpc_unregister_policy(struct ptlrpc_sec_policy *policy)
95 {
96         __u16 number = policy->sp_policy;
97
98         LASSERT(number < SPTLRPC_POLICY_MAX);
99
100         write_lock(&policy_lock);
101         if (unlikely(policies[number] == NULL)) {
102                 write_unlock(&policy_lock);
103                 CERROR("%s: already unregistered\n", policy->sp_name);
104                 return -EINVAL;
105         }
106
107         LASSERT(policies[number] == policy);
108         policies[number] = NULL;
109         write_unlock(&policy_lock);
110
111         CDEBUG(D_SEC, "%s: unregistered\n", policy->sp_name);
112         return 0;
113 }
114 EXPORT_SYMBOL(sptlrpc_unregister_policy);
115
116 static
117 struct ptlrpc_sec_policy * sptlrpc_wireflavor2policy(__u32 flavor)
118 {
119         static DEFINE_MUTEX(load_mutex);
120         static atomic_t           loaded = ATOMIC_INIT(0);
121         struct ptlrpc_sec_policy *policy;
122         __u16                     number = SPTLRPC_FLVR_POLICY(flavor);
123         __u16                     flag = 0;
124
125         if (number >= SPTLRPC_POLICY_MAX)
126                 return NULL;
127
128         while (1) {
129                 read_lock(&policy_lock);
130                 policy = policies[number];
131                 if (policy && !try_module_get(policy->sp_owner))
132                         policy = NULL;
133                 if (policy == NULL)
134                         flag = atomic_read(&loaded);
135                 read_unlock(&policy_lock);
136
137                 if (policy != NULL || flag != 0 ||
138                     number != SPTLRPC_POLICY_GSS)
139                         break;
140
141                 /* try to load gss module, once */
142                 mutex_lock(&load_mutex);
143                 if (atomic_read(&loaded) == 0) {
144                         if (request_module("ptlrpc_gss") == 0)
145                                 CDEBUG(D_SEC,
146                                        "module ptlrpc_gss loaded on demand\n");
147                         else
148                                 CERROR("Unable to load module ptlrpc_gss\n");
149
150                         atomic_set(&loaded, 1);
151                 }
152                 mutex_unlock(&load_mutex);
153         }
154
155         return policy;
156 }
157
158 __u32 sptlrpc_name2flavor_base(const char *name)
159 {
160         if (!strcmp(name, "null"))
161                 return SPTLRPC_FLVR_NULL;
162         if (!strcmp(name, "plain"))
163                 return SPTLRPC_FLVR_PLAIN;
164         if (!strcmp(name, "gssnull"))
165                 return SPTLRPC_FLVR_GSSNULL;
166         if (!strcmp(name, "krb5n"))
167                 return SPTLRPC_FLVR_KRB5N;
168         if (!strcmp(name, "krb5a"))
169                 return SPTLRPC_FLVR_KRB5A;
170         if (!strcmp(name, "krb5i"))
171                 return SPTLRPC_FLVR_KRB5I;
172         if (!strcmp(name, "krb5p"))
173                 return SPTLRPC_FLVR_KRB5P;
174         if (!strcmp(name, "ski"))
175                 return SPTLRPC_FLVR_SKI;
176         if (!strcmp(name, "skpi"))
177                 return SPTLRPC_FLVR_SKPI;
178
179         return SPTLRPC_FLVR_INVALID;
180 }
181 EXPORT_SYMBOL(sptlrpc_name2flavor_base);
182
183 const char *sptlrpc_flavor2name_base(__u32 flvr)
184 {
185         __u32   base = SPTLRPC_FLVR_BASE(flvr);
186
187         if (base == SPTLRPC_FLVR_BASE(SPTLRPC_FLVR_NULL))
188                 return "null";
189         else if (base == SPTLRPC_FLVR_BASE(SPTLRPC_FLVR_PLAIN))
190                 return "plain";
191         else if (base == SPTLRPC_FLVR_BASE(SPTLRPC_FLVR_GSSNULL))
192                 return "gssnull";
193         else if (base == SPTLRPC_FLVR_BASE(SPTLRPC_FLVR_KRB5N))
194                 return "krb5n";
195         else if (base == SPTLRPC_FLVR_BASE(SPTLRPC_FLVR_KRB5A))
196                 return "krb5a";
197         else if (base == SPTLRPC_FLVR_BASE(SPTLRPC_FLVR_KRB5I))
198                 return "krb5i";
199         else if (base == SPTLRPC_FLVR_BASE(SPTLRPC_FLVR_KRB5P))
200                 return "krb5p";
201         else if (base == SPTLRPC_FLVR_BASE(SPTLRPC_FLVR_SKI))
202                 return "ski";
203         else if (base == SPTLRPC_FLVR_BASE(SPTLRPC_FLVR_SKPI))
204                 return "skpi";
205
206         CERROR("invalid wire flavor 0x%x\n", flvr);
207         return "invalid";
208 }
209 EXPORT_SYMBOL(sptlrpc_flavor2name_base);
210
211 char *sptlrpc_flavor2name_bulk(struct sptlrpc_flavor *sf,
212                                char *buf, int bufsize)
213 {
214         if (SPTLRPC_FLVR_POLICY(sf->sf_rpc) == SPTLRPC_POLICY_PLAIN)
215                 snprintf(buf, bufsize, "hash:%s",
216                          sptlrpc_get_hash_name(sf->u_bulk.hash.hash_alg));
217         else
218                 snprintf(buf, bufsize, "%s",
219                          sptlrpc_flavor2name_base(sf->sf_rpc));
220
221         buf[bufsize - 1] = '\0';
222         return buf;
223 }
224 EXPORT_SYMBOL(sptlrpc_flavor2name_bulk);
225
226 char *sptlrpc_flavor2name(struct sptlrpc_flavor *sf, char *buf, int bufsize)
227 {
228         snprintf(buf, bufsize, "%s", sptlrpc_flavor2name_base(sf->sf_rpc));
229
230         /*
231          * currently we don't support customized bulk specification for
232          * flavors other than plain
233          */
234         if (SPTLRPC_FLVR_POLICY(sf->sf_rpc) == SPTLRPC_POLICY_PLAIN) {
235                 char bspec[16];
236
237                 bspec[0] = '-';
238                 sptlrpc_flavor2name_bulk(sf, &bspec[1], sizeof(bspec) - 1);
239                 strncat(buf, bspec, bufsize);
240         }
241
242         buf[bufsize - 1] = '\0';
243         return buf;
244 }
245 EXPORT_SYMBOL(sptlrpc_flavor2name);
246
247 char *sptlrpc_secflags2str(__u32 flags, char *buf, int bufsize)
248 {
249         buf[0] = '\0';
250
251         if (flags & PTLRPC_SEC_FL_REVERSE)
252                 strlcat(buf, "reverse,", bufsize);
253         if (flags & PTLRPC_SEC_FL_ROOTONLY)
254                 strlcat(buf, "rootonly,", bufsize);
255         if (flags & PTLRPC_SEC_FL_UDESC)
256                 strlcat(buf, "udesc,", bufsize);
257         if (flags & PTLRPC_SEC_FL_BULK)
258                 strlcat(buf, "bulk,", bufsize);
259         if (buf[0] == '\0')
260                 strlcat(buf, "-,", bufsize);
261
262         return buf;
263 }
264 EXPORT_SYMBOL(sptlrpc_secflags2str);
265
266 /**************************************************
267  * client context APIs                            *
268  **************************************************/
269
270 static
271 struct ptlrpc_cli_ctx *get_my_ctx(struct ptlrpc_sec *sec)
272 {
273         struct vfs_cred vcred;
274         int create = 1, remove_dead = 1;
275
276         LASSERT(sec);
277         LASSERT(sec->ps_policy->sp_cops->lookup_ctx);
278
279         if (sec->ps_flvr.sf_flags & (PTLRPC_SEC_FL_REVERSE |
280                                      PTLRPC_SEC_FL_ROOTONLY)) {
281                 vcred.vc_uid = 0;
282                 vcred.vc_gid = 0;
283                 if (sec->ps_flvr.sf_flags & PTLRPC_SEC_FL_REVERSE) {
284                         create = 0;
285                         remove_dead = 0;
286                 }
287         } else {
288                 vcred.vc_uid = from_kuid(&init_user_ns, current_uid());
289                 vcred.vc_gid = from_kgid(&init_user_ns, current_gid());
290         }
291
292         return sec->ps_policy->sp_cops->lookup_ctx(sec, &vcred, create,
293                                                    remove_dead);
294 }
295
296 struct ptlrpc_cli_ctx *sptlrpc_cli_ctx_get(struct ptlrpc_cli_ctx *ctx)
297 {
298         atomic_inc(&ctx->cc_refcount);
299         return ctx;
300 }
301 EXPORT_SYMBOL(sptlrpc_cli_ctx_get);
302
303 void sptlrpc_cli_ctx_put(struct ptlrpc_cli_ctx *ctx, int sync)
304 {
305         struct ptlrpc_sec *sec = ctx->cc_sec;
306
307         LASSERT(sec);
308         LASSERT_ATOMIC_POS(&ctx->cc_refcount);
309
310         if (!atomic_dec_and_test(&ctx->cc_refcount))
311                 return;
312
313         sec->ps_policy->sp_cops->release_ctx(sec, ctx, sync);
314 }
315 EXPORT_SYMBOL(sptlrpc_cli_ctx_put);
316
317 /**
318  * Expire the client context immediately.
319  *
320  * \pre Caller must hold at least 1 reference on the \a ctx.
321  */
322 void sptlrpc_cli_ctx_expire(struct ptlrpc_cli_ctx *ctx)
323 {
324         LASSERT(ctx->cc_ops->die);
325         ctx->cc_ops->die(ctx, 0);
326 }
327 EXPORT_SYMBOL(sptlrpc_cli_ctx_expire);
328
329 /**
330  * To wake up the threads who are waiting for this client context. Called
331  * after some status change happened on \a ctx.
332  */
333 void sptlrpc_cli_ctx_wakeup(struct ptlrpc_cli_ctx *ctx)
334 {
335         struct ptlrpc_request *req, *next;
336
337         spin_lock(&ctx->cc_lock);
338         list_for_each_entry_safe(req, next, &ctx->cc_req_list,
339                                      rq_ctx_chain) {
340                 list_del_init(&req->rq_ctx_chain);
341                 ptlrpc_client_wake_req(req);
342         }
343         spin_unlock(&ctx->cc_lock);
344 }
345 EXPORT_SYMBOL(sptlrpc_cli_ctx_wakeup);
346
347 int sptlrpc_cli_ctx_display(struct ptlrpc_cli_ctx *ctx, char *buf, int bufsize)
348 {
349         LASSERT(ctx->cc_ops);
350
351         if (ctx->cc_ops->display == NULL)
352                 return 0;
353
354         return ctx->cc_ops->display(ctx, buf, bufsize);
355 }
356
357 static int import_sec_check_expire(struct obd_import *imp)
358 {
359         int     adapt = 0;
360
361         spin_lock(&imp->imp_lock);
362         if (imp->imp_sec_expire &&
363             imp->imp_sec_expire < cfs_time_current_sec()) {
364                 adapt = 1;
365                 imp->imp_sec_expire = 0;
366         }
367         spin_unlock(&imp->imp_lock);
368
369         if (!adapt)
370                 return 0;
371
372         CDEBUG(D_SEC, "found delayed sec adapt expired, do it now\n");
373         return sptlrpc_import_sec_adapt(imp, NULL, NULL);
374 }
375
376 /**
377  * Get and validate the client side ptlrpc security facilities from
378  * \a imp. There is a race condition on client reconnect when the import is
379  * being destroyed while there are outstanding client bound requests. In
380  * this case do not output any error messages if import secuity is not
381  * found.
382  *
383  * \param[in] imp obd import associated with client
384  * \param[out] sec client side ptlrpc security
385  *
386  * \retval 0 if security retrieved successfully
387  * \retval -ve errno if there was a problem
388  */
389 static int import_sec_validate_get(struct obd_import *imp,
390                                    struct ptlrpc_sec **sec)
391 {
392         int     rc;
393
394         if (unlikely(imp->imp_sec_expire)) {
395                 rc = import_sec_check_expire(imp);
396                 if (rc)
397                         return rc;
398         }
399
400         *sec = sptlrpc_import_sec_ref(imp);
401         /* Only output an error when the import is still active */
402         if (*sec == NULL) {
403                 if (list_empty(&imp->imp_zombie_chain))
404                         CERROR("import %p (%s) with no sec\n",
405                                 imp, ptlrpc_import_state_name(imp->imp_state));
406                 return -EACCES;
407         }
408
409         if (unlikely((*sec)->ps_dying)) {
410                 CERROR("attempt to use dying sec %p\n", sec);
411                 sptlrpc_sec_put(*sec);
412                 return -EACCES;
413         }
414
415         return 0;
416 }
417
418 /**
419  * Given a \a req, find or allocate an appropriate context for it.
420  * \pre req->rq_cli_ctx == NULL.
421  *
422  * \retval 0 succeed, and req->rq_cli_ctx is set.
423  * \retval -ev error number, and req->rq_cli_ctx == NULL.
424  */
425 int sptlrpc_req_get_ctx(struct ptlrpc_request *req)
426 {
427         struct obd_import *imp = req->rq_import;
428         struct ptlrpc_sec *sec;
429         int                rc;
430         ENTRY;
431
432         LASSERT(!req->rq_cli_ctx);
433         LASSERT(imp);
434
435         rc = import_sec_validate_get(imp, &sec);
436         if (rc)
437                 RETURN(rc);
438
439         req->rq_cli_ctx = get_my_ctx(sec);
440
441         sptlrpc_sec_put(sec);
442
443         if (!req->rq_cli_ctx) {
444                 CERROR("req %p: fail to get context\n", req);
445                 RETURN(-ECONNREFUSED);
446         }
447
448         RETURN(0);
449 }
450
451 /**
452  * Drop the context for \a req.
453  * \pre req->rq_cli_ctx != NULL.
454  * \post req->rq_cli_ctx == NULL.
455  *
456  * If \a sync == 0, this function should return quickly without sleep;
457  * otherwise it might trigger and wait for the whole process of sending
458  * an context-destroying rpc to server.
459  */
460 void sptlrpc_req_put_ctx(struct ptlrpc_request *req, int sync)
461 {
462         ENTRY;
463
464         LASSERT(req);
465         LASSERT(req->rq_cli_ctx);
466
467         /* request might be asked to release earlier while still
468          * in the context waiting list.
469          */
470         if (!list_empty(&req->rq_ctx_chain)) {
471                 spin_lock(&req->rq_cli_ctx->cc_lock);
472                 list_del_init(&req->rq_ctx_chain);
473                 spin_unlock(&req->rq_cli_ctx->cc_lock);
474         }
475
476         sptlrpc_cli_ctx_put(req->rq_cli_ctx, sync);
477         req->rq_cli_ctx = NULL;
478         EXIT;
479 }
480
481 static
482 int sptlrpc_req_ctx_switch(struct ptlrpc_request *req,
483                            struct ptlrpc_cli_ctx *oldctx,
484                            struct ptlrpc_cli_ctx *newctx)
485 {
486         struct sptlrpc_flavor   old_flvr;
487         char                   *reqmsg = NULL; /* to workaround old gcc */
488         int                     reqmsg_size;
489         int                     rc = 0;
490
491         LASSERT(req->rq_reqmsg);
492         LASSERT(req->rq_reqlen);
493         LASSERT(req->rq_replen);
494
495         CDEBUG(D_SEC, "req %p: switch ctx %p(%u->%s) -> %p(%u->%s), "
496                "switch sec %p(%s) -> %p(%s)\n", req,
497                oldctx, oldctx->cc_vcred.vc_uid, sec2target_str(oldctx->cc_sec),
498                newctx, newctx->cc_vcred.vc_uid, sec2target_str(newctx->cc_sec),
499                oldctx->cc_sec, oldctx->cc_sec->ps_policy->sp_name,
500                newctx->cc_sec, newctx->cc_sec->ps_policy->sp_name);
501
502         /* save flavor */
503         old_flvr = req->rq_flvr;
504
505         /* save request message */
506         reqmsg_size = req->rq_reqlen;
507         if (reqmsg_size != 0) {
508                 OBD_ALLOC_LARGE(reqmsg, reqmsg_size);
509                 if (reqmsg == NULL)
510                         return -ENOMEM;
511                 memcpy(reqmsg, req->rq_reqmsg, reqmsg_size);
512         }
513
514         /* release old req/rep buf */
515         req->rq_cli_ctx = oldctx;
516         sptlrpc_cli_free_reqbuf(req);
517         sptlrpc_cli_free_repbuf(req);
518         req->rq_cli_ctx = newctx;
519
520         /* recalculate the flavor */
521         sptlrpc_req_set_flavor(req, 0);
522
523         /* alloc new request buffer
524          * we don't need to alloc reply buffer here, leave it to the
525          * rest procedure of ptlrpc */
526         if (reqmsg_size != 0) {
527                 rc = sptlrpc_cli_alloc_reqbuf(req, reqmsg_size);
528                 if (!rc) {
529                         LASSERT(req->rq_reqmsg);
530                         memcpy(req->rq_reqmsg, reqmsg, reqmsg_size);
531                 } else {
532                         CWARN("failed to alloc reqbuf: %d\n", rc);
533                         req->rq_flvr = old_flvr;
534                 }
535
536                 OBD_FREE_LARGE(reqmsg, reqmsg_size);
537         }
538         return rc;
539 }
540
541 /**
542  * If current context of \a req is dead somehow, e.g. we just switched flavor
543  * thus marked original contexts dead, we'll find a new context for it. if
544  * no switch is needed, \a req will end up with the same context.
545  *
546  * \note a request must have a context, to keep other parts of code happy.
547  * In any case of failure during the switching, we must restore the old one.
548  */
549 int sptlrpc_req_replace_dead_ctx(struct ptlrpc_request *req)
550 {
551         struct ptlrpc_cli_ctx *oldctx = req->rq_cli_ctx;
552         struct ptlrpc_cli_ctx *newctx;
553         int                    rc;
554         ENTRY;
555
556         LASSERT(oldctx);
557
558         sptlrpc_cli_ctx_get(oldctx);
559         sptlrpc_req_put_ctx(req, 0);
560
561         rc = sptlrpc_req_get_ctx(req);
562         if (unlikely(rc)) {
563                 LASSERT(!req->rq_cli_ctx);
564
565                 /* restore old ctx */
566                 req->rq_cli_ctx = oldctx;
567                 RETURN(rc);
568         }
569
570         newctx = req->rq_cli_ctx;
571         LASSERT(newctx);
572
573         if (unlikely(newctx == oldctx &&
574                      test_bit(PTLRPC_CTX_DEAD_BIT, &oldctx->cc_flags))) {
575                 /*
576                  * still get the old dead ctx, usually means system too busy
577                  */
578                 CDEBUG(D_SEC,
579                        "ctx (%p, fl %lx) doesn't switch, relax a little bit\n",
580                        newctx, newctx->cc_flags);
581
582                 set_current_state(TASK_INTERRUPTIBLE);
583                 schedule_timeout(msecs_to_jiffies(MSEC_PER_SEC));
584         } else {
585                 /*
586                  * it's possible newctx == oldctx if we're switching
587                  * subflavor with the same sec.
588                  */
589                 rc = sptlrpc_req_ctx_switch(req, oldctx, newctx);
590                 if (rc) {
591                         /* restore old ctx */
592                         sptlrpc_req_put_ctx(req, 0);
593                         req->rq_cli_ctx = oldctx;
594                         RETURN(rc);
595                 }
596
597                 LASSERT(req->rq_cli_ctx == newctx);
598         }
599
600         sptlrpc_cli_ctx_put(oldctx, 1);
601         RETURN(0);
602 }
603 EXPORT_SYMBOL(sptlrpc_req_replace_dead_ctx);
604
605 static
606 int ctx_check_refresh(struct ptlrpc_cli_ctx *ctx)
607 {
608         if (cli_ctx_is_refreshed(ctx))
609                 return 1;
610         return 0;
611 }
612
613 static
614 int ctx_refresh_timeout(void *data)
615 {
616         struct ptlrpc_request *req = data;
617         int rc;
618
619         /* conn_cnt is needed in expire_one_request */
620         lustre_msg_set_conn_cnt(req->rq_reqmsg, req->rq_import->imp_conn_cnt);
621
622         rc = ptlrpc_expire_one_request(req, 1);
623         /* if we started recovery, we should mark this ctx dead; otherwise
624          * in case of lgssd died nobody would retire this ctx, following
625          * connecting will still find the same ctx thus cause deadlock.
626          * there's an assumption that expire time of the request should be
627          * later than the context refresh expire time.
628          */
629         if (rc == 0)
630                 req->rq_cli_ctx->cc_ops->die(req->rq_cli_ctx, 0);
631         return rc;
632 }
633
634 static
635 void ctx_refresh_interrupt(void *data)
636 {
637         struct ptlrpc_request *req = data;
638
639         spin_lock(&req->rq_lock);
640         req->rq_intr = 1;
641         spin_unlock(&req->rq_lock);
642 }
643
644 static
645 void req_off_ctx_list(struct ptlrpc_request *req, struct ptlrpc_cli_ctx *ctx)
646 {
647         spin_lock(&ctx->cc_lock);
648         if (!list_empty(&req->rq_ctx_chain))
649                 list_del_init(&req->rq_ctx_chain);
650         spin_unlock(&ctx->cc_lock);
651 }
652
653 /**
654  * To refresh the context of \req, if it's not up-to-date.
655  * \param timeout
656  * - < 0: don't wait
657  * - = 0: wait until success or fatal error occur
658  * - > 0: timeout value (in seconds)
659  *
660  * The status of the context could be subject to be changed by other threads
661  * at any time. We allow this race, but once we return with 0, the caller will
662  * suppose it's uptodated and keep using it until the owning rpc is done.
663  *
664  * \retval 0 only if the context is uptodated.
665  * \retval -ev error number.
666  */
667 int sptlrpc_req_refresh_ctx(struct ptlrpc_request *req, long timeout)
668 {
669         struct ptlrpc_cli_ctx  *ctx = req->rq_cli_ctx;
670         struct ptlrpc_sec      *sec;
671         struct l_wait_info      lwi;
672         int                     rc;
673         ENTRY;
674
675         LASSERT(ctx);
676
677         if (req->rq_ctx_init || req->rq_ctx_fini)
678                 RETURN(0);
679
680         /*
681          * during the process a request's context might change type even
682          * (e.g. from gss ctx to null ctx), so each loop we need to re-check
683          * everything
684          */
685 again:
686         rc = import_sec_validate_get(req->rq_import, &sec);
687         if (rc)
688                 RETURN(rc);
689
690         if (sec->ps_flvr.sf_rpc != req->rq_flvr.sf_rpc) {
691                 CDEBUG(D_SEC, "req %p: flavor has changed %x -> %x\n",
692                       req, req->rq_flvr.sf_rpc, sec->ps_flvr.sf_rpc);
693                 req_off_ctx_list(req, ctx);
694                 sptlrpc_req_replace_dead_ctx(req);
695                 ctx = req->rq_cli_ctx;
696         }
697         sptlrpc_sec_put(sec);
698
699         if (cli_ctx_is_eternal(ctx))
700                 RETURN(0);
701
702         if (unlikely(test_bit(PTLRPC_CTX_NEW_BIT, &ctx->cc_flags))) {
703                 LASSERT(ctx->cc_ops->refresh);
704                 ctx->cc_ops->refresh(ctx);
705         }
706         LASSERT(test_bit(PTLRPC_CTX_NEW_BIT, &ctx->cc_flags) == 0);
707
708         LASSERT(ctx->cc_ops->validate);
709         if (ctx->cc_ops->validate(ctx) == 0) {
710                 req_off_ctx_list(req, ctx);
711                 RETURN(0);
712         }
713
714         if (unlikely(test_bit(PTLRPC_CTX_ERROR_BIT, &ctx->cc_flags))) {
715                 spin_lock(&req->rq_lock);
716                 req->rq_err = 1;
717                 spin_unlock(&req->rq_lock);
718                 req_off_ctx_list(req, ctx);
719                 RETURN(-EPERM);
720         }
721
722         /*
723          * There's a subtle issue for resending RPCs, suppose following
724          * situation:
725          *  1. the request was sent to server.
726          *  2. recovery was kicked start, after finished the request was
727          *     marked as resent.
728          *  3. resend the request.
729          *  4. old reply from server received, we accept and verify the reply.
730          *     this has to be success, otherwise the error will be aware
731          *     by application.
732          *  5. new reply from server received, dropped by LNet.
733          *
734          * Note the xid of old & new request is the same. We can't simply
735          * change xid for the resent request because the server replies on
736          * it for reply reconstruction.
737          *
738          * Commonly the original context should be uptodate because we
739          * have an expiry nice time; server will keep its context because
740          * we at least hold a ref of old context which prevent context
741          * from destroying RPC being sent. So server still can accept the
742          * request and finish the RPC. But if that's not the case:
743          *  1. If server side context has been trimmed, a NO_CONTEXT will
744          *     be returned, gss_cli_ctx_verify/unseal will switch to new
745          *     context by force.
746          *  2. Current context never be refreshed, then we are fine: we
747          *     never really send request with old context before.
748          */
749         if (test_bit(PTLRPC_CTX_UPTODATE_BIT, &ctx->cc_flags) &&
750             unlikely(req->rq_reqmsg) &&
751             lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT) {
752                 req_off_ctx_list(req, ctx);
753                 RETURN(0);
754         }
755
756         if (unlikely(test_bit(PTLRPC_CTX_DEAD_BIT, &ctx->cc_flags))) {
757                 req_off_ctx_list(req, ctx);
758                 /*
759                  * don't switch ctx if import was deactivated
760                  */
761                 if (req->rq_import->imp_deactive) {
762                         spin_lock(&req->rq_lock);
763                         req->rq_err = 1;
764                         spin_unlock(&req->rq_lock);
765                         RETURN(-EINTR);
766                 }
767
768                 rc = sptlrpc_req_replace_dead_ctx(req);
769                 if (rc) {
770                         LASSERT(ctx == req->rq_cli_ctx);
771                         CERROR("req %p: failed to replace dead ctx %p: %d\n",
772                                req, ctx, rc);
773                         spin_lock(&req->rq_lock);
774                         req->rq_err = 1;
775                         spin_unlock(&req->rq_lock);
776                         RETURN(rc);
777                 }
778
779                 ctx = req->rq_cli_ctx;
780                 goto again;
781         }
782
783         /*
784          * Now we're sure this context is during upcall, add myself into
785          * waiting list
786          */
787         spin_lock(&ctx->cc_lock);
788         if (list_empty(&req->rq_ctx_chain))
789                 list_add(&req->rq_ctx_chain, &ctx->cc_req_list);
790         spin_unlock(&ctx->cc_lock);
791
792         if (timeout < 0)
793                 RETURN(-EWOULDBLOCK);
794
795         /* Clear any flags that may be present from previous sends */
796         LASSERT(req->rq_receiving_reply == 0);
797         spin_lock(&req->rq_lock);
798         req->rq_err = 0;
799         req->rq_timedout = 0;
800         req->rq_resend = 0;
801         req->rq_restart = 0;
802         spin_unlock(&req->rq_lock);
803
804         lwi = LWI_TIMEOUT_INTR(msecs_to_jiffies(timeout * MSEC_PER_SEC),
805                                ctx_refresh_timeout,
806                                ctx_refresh_interrupt, req);
807         rc = l_wait_event(req->rq_reply_waitq, ctx_check_refresh(ctx), &lwi);
808
809         /*
810          * following cases could lead us here:
811          * - successfully refreshed;
812          * - interrupted;
813          * - timedout, and we don't want recover from the failure;
814          * - timedout, and waked up upon recovery finished;
815          * - someone else mark this ctx dead by force;
816          * - someone invalidate the req and call ptlrpc_client_wake_req(),
817          *   e.g. ptlrpc_abort_inflight();
818          */
819         if (!cli_ctx_is_refreshed(ctx)) {
820                 /* timed out or interruptted */
821                 req_off_ctx_list(req, ctx);
822
823                 LASSERT(rc != 0);
824                 RETURN(rc);
825         }
826
827         goto again;
828 }
829
830 /**
831  * Initialize flavor settings for \a req, according to \a opcode.
832  *
833  * \note this could be called in two situations:
834  * - new request from ptlrpc_pre_req(), with proper @opcode
835  * - old request which changed ctx in the middle, with @opcode == 0
836  */
837 void sptlrpc_req_set_flavor(struct ptlrpc_request *req, int opcode)
838 {
839         struct ptlrpc_sec *sec;
840
841         LASSERT(req->rq_import);
842         LASSERT(req->rq_cli_ctx);
843         LASSERT(req->rq_cli_ctx->cc_sec);
844         LASSERT(req->rq_bulk_read == 0 || req->rq_bulk_write == 0);
845
846         /* special security flags accoding to opcode */
847         switch (opcode) {
848         case OST_READ:
849         case MDS_READPAGE:
850         case MGS_CONFIG_READ:
851         case OBD_IDX_READ:
852                 req->rq_bulk_read = 1;
853                 break;
854         case OST_WRITE:
855         case MDS_WRITEPAGE:
856                 req->rq_bulk_write = 1;
857                 break;
858         case SEC_CTX_INIT:
859                 req->rq_ctx_init = 1;
860                 break;
861         case SEC_CTX_FINI:
862                 req->rq_ctx_fini = 1;
863                 break;
864         case 0:
865                 /* init/fini rpc won't be resend, so can't be here */
866                 LASSERT(req->rq_ctx_init == 0);
867                 LASSERT(req->rq_ctx_fini == 0);
868
869                 /* cleanup flags, which should be recalculated */
870                 req->rq_pack_udesc = 0;
871                 req->rq_pack_bulk = 0;
872                 break;
873         }
874
875         sec = req->rq_cli_ctx->cc_sec;
876
877         spin_lock(&sec->ps_lock);
878         req->rq_flvr = sec->ps_flvr;
879         spin_unlock(&sec->ps_lock);
880
881         /* force SVC_NULL for context initiation rpc, SVC_INTG for context
882          * destruction rpc */
883         if (unlikely(req->rq_ctx_init))
884                 flvr_set_svc(&req->rq_flvr.sf_rpc, SPTLRPC_SVC_NULL);
885         else if (unlikely(req->rq_ctx_fini))
886                 flvr_set_svc(&req->rq_flvr.sf_rpc, SPTLRPC_SVC_INTG);
887
888         /* user descriptor flag, null security can't do it anyway */
889         if ((sec->ps_flvr.sf_flags & PTLRPC_SEC_FL_UDESC) &&
890             (req->rq_flvr.sf_rpc != SPTLRPC_FLVR_NULL))
891                 req->rq_pack_udesc = 1;
892
893         /* bulk security flag */
894         if ((req->rq_bulk_read || req->rq_bulk_write) &&
895             sptlrpc_flavor_has_bulk(&req->rq_flvr))
896                 req->rq_pack_bulk = 1;
897 }
898
899 void sptlrpc_request_out_callback(struct ptlrpc_request *req)
900 {
901         if (SPTLRPC_FLVR_SVC(req->rq_flvr.sf_rpc) != SPTLRPC_SVC_PRIV)
902                 return;
903
904         LASSERT(req->rq_clrbuf);
905         if (req->rq_pool || !req->rq_reqbuf)
906                 return;
907
908         OBD_FREE(req->rq_reqbuf, req->rq_reqbuf_len);
909         req->rq_reqbuf = NULL;
910         req->rq_reqbuf_len = 0;
911 }
912
913 /**
914  * Given an import \a imp, check whether current user has a valid context
915  * or not. We may create a new context and try to refresh it, and try
916  * repeatedly try in case of non-fatal errors. Return 0 means success.
917  */
918 int sptlrpc_import_check_ctx(struct obd_import *imp)
919 {
920         struct ptlrpc_sec     *sec;
921         struct ptlrpc_cli_ctx *ctx;
922         struct ptlrpc_request *req = NULL;
923         int rc;
924         ENTRY;
925
926         might_sleep();
927
928         sec = sptlrpc_import_sec_ref(imp);
929         ctx = get_my_ctx(sec);
930         sptlrpc_sec_put(sec);
931
932         if (!ctx)
933                 RETURN(-ENOMEM);
934
935         if (cli_ctx_is_eternal(ctx) ||
936             ctx->cc_ops->validate(ctx) == 0) {
937                 sptlrpc_cli_ctx_put(ctx, 1);
938                 RETURN(0);
939         }
940
941         if (cli_ctx_is_error(ctx)) {
942                 sptlrpc_cli_ctx_put(ctx, 1);
943                 RETURN(-EACCES);
944         }
945
946         req = ptlrpc_request_cache_alloc(GFP_NOFS);
947         if (!req)
948                 RETURN(-ENOMEM);
949
950         ptlrpc_cli_req_init(req);
951         atomic_set(&req->rq_refcount, 10000);
952
953         req->rq_import = imp;
954         req->rq_flvr = sec->ps_flvr;
955         req->rq_cli_ctx = ctx;
956
957         rc = sptlrpc_req_refresh_ctx(req, 0);
958         LASSERT(list_empty(&req->rq_ctx_chain));
959         sptlrpc_cli_ctx_put(req->rq_cli_ctx, 1);
960         ptlrpc_request_cache_free(req);
961
962         RETURN(rc);
963 }
964
965 /**
966  * Used by ptlrpc client, to perform the pre-defined security transformation
967  * upon the request message of \a req. After this function called,
968  * req->rq_reqmsg is still accessible as clear text.
969  */
970 int sptlrpc_cli_wrap_request(struct ptlrpc_request *req)
971 {
972         struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx;
973         int rc = 0;
974         ENTRY;
975
976         LASSERT(ctx);
977         LASSERT(ctx->cc_sec);
978         LASSERT(req->rq_reqbuf || req->rq_clrbuf);
979
980         /* we wrap bulk request here because now we can be sure
981          * the context is uptodate.
982          */
983         if (req->rq_bulk) {
984                 rc = sptlrpc_cli_wrap_bulk(req, req->rq_bulk);
985                 if (rc)
986                         RETURN(rc);
987         }
988
989         switch (SPTLRPC_FLVR_SVC(req->rq_flvr.sf_rpc)) {
990         case SPTLRPC_SVC_NULL:
991         case SPTLRPC_SVC_AUTH:
992         case SPTLRPC_SVC_INTG:
993                 LASSERT(ctx->cc_ops->sign);
994                 rc = ctx->cc_ops->sign(ctx, req);
995                 break;
996         case SPTLRPC_SVC_PRIV:
997                 LASSERT(ctx->cc_ops->seal);
998                 rc = ctx->cc_ops->seal(ctx, req);
999                 break;
1000         default:
1001                 LBUG();
1002         }
1003
1004         if (rc == 0) {
1005                 LASSERT(req->rq_reqdata_len);
1006                 LASSERT(req->rq_reqdata_len % 8 == 0);
1007                 LASSERT(req->rq_reqdata_len <= req->rq_reqbuf_len);
1008         }
1009
1010         RETURN(rc);
1011 }
1012
1013 static int do_cli_unwrap_reply(struct ptlrpc_request *req)
1014 {
1015         struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx;
1016         int                    rc;
1017         ENTRY;
1018
1019         LASSERT(ctx);
1020         LASSERT(ctx->cc_sec);
1021         LASSERT(req->rq_repbuf);
1022         LASSERT(req->rq_repdata);
1023         LASSERT(req->rq_repmsg == NULL);
1024
1025         req->rq_rep_swab_mask = 0;
1026
1027         rc = __lustre_unpack_msg(req->rq_repdata, req->rq_repdata_len);
1028         switch (rc) {
1029         case 1:
1030                 lustre_set_rep_swabbed(req, MSG_PTLRPC_HEADER_OFF);
1031         case 0:
1032                 break;
1033         default:
1034                 CERROR("failed unpack reply: x"LPU64"\n", req->rq_xid);
1035                 RETURN(-EPROTO);
1036         }
1037
1038         if (req->rq_repdata_len < sizeof(struct lustre_msg)) {
1039                 CERROR("replied data length %d too small\n",
1040                        req->rq_repdata_len);
1041                 RETURN(-EPROTO);
1042         }
1043
1044         if (SPTLRPC_FLVR_POLICY(req->rq_repdata->lm_secflvr) !=
1045             SPTLRPC_FLVR_POLICY(req->rq_flvr.sf_rpc)) {
1046                 CERROR("reply policy %u doesn't match request policy %u\n",
1047                        SPTLRPC_FLVR_POLICY(req->rq_repdata->lm_secflvr),
1048                        SPTLRPC_FLVR_POLICY(req->rq_flvr.sf_rpc));
1049                 RETURN(-EPROTO);
1050         }
1051
1052         switch (SPTLRPC_FLVR_SVC(req->rq_flvr.sf_rpc)) {
1053         case SPTLRPC_SVC_NULL:
1054         case SPTLRPC_SVC_AUTH:
1055         case SPTLRPC_SVC_INTG:
1056                 LASSERT(ctx->cc_ops->verify);
1057                 rc = ctx->cc_ops->verify(ctx, req);
1058                 break;
1059         case SPTLRPC_SVC_PRIV:
1060                 LASSERT(ctx->cc_ops->unseal);
1061                 rc = ctx->cc_ops->unseal(ctx, req);
1062                 break;
1063         default:
1064                 LBUG();
1065         }
1066         LASSERT(rc || req->rq_repmsg || req->rq_resend);
1067
1068         if (SPTLRPC_FLVR_POLICY(req->rq_flvr.sf_rpc) != SPTLRPC_POLICY_NULL &&
1069             !req->rq_ctx_init)
1070                 req->rq_rep_swab_mask = 0;
1071         RETURN(rc);
1072 }
1073
1074 /**
1075  * Used by ptlrpc client, to perform security transformation upon the reply
1076  * message of \a req. After return successfully, req->rq_repmsg points to
1077  * the reply message in clear text.
1078  *
1079  * \pre the reply buffer should have been un-posted from LNet, so nothing is
1080  * going to change.
1081  */
1082 int sptlrpc_cli_unwrap_reply(struct ptlrpc_request *req)
1083 {
1084         LASSERT(req->rq_repbuf);
1085         LASSERT(req->rq_repdata == NULL);
1086         LASSERT(req->rq_repmsg == NULL);
1087         LASSERT(req->rq_reply_off + req->rq_nob_received <= req->rq_repbuf_len);
1088
1089         if (req->rq_reply_off == 0 &&
1090             (lustre_msghdr_get_flags(req->rq_reqmsg) & MSGHDR_AT_SUPPORT)) {
1091                 CERROR("real reply with offset 0\n");
1092                 return -EPROTO;
1093         }
1094
1095         if (req->rq_reply_off % 8 != 0) {
1096                 CERROR("reply at odd offset %u\n", req->rq_reply_off);
1097                 return -EPROTO;
1098         }
1099
1100         req->rq_repdata = (struct lustre_msg *)
1101                                 (req->rq_repbuf + req->rq_reply_off);
1102         req->rq_repdata_len = req->rq_nob_received;
1103
1104         return do_cli_unwrap_reply(req);
1105 }
1106
1107 /**
1108  * Used by ptlrpc client, to perform security transformation upon the early
1109  * reply message of \a req. We expect the rq_reply_off is 0, and
1110  * rq_nob_received is the early reply size.
1111  * 
1112  * Because the receive buffer might be still posted, the reply data might be
1113  * changed at any time, no matter we're holding rq_lock or not. For this reason
1114  * we allocate a separate ptlrpc_request and reply buffer for early reply
1115  * processing.
1116  *
1117  * \retval 0 success, \a req_ret is filled with a duplicated ptlrpc_request.
1118  * Later the caller must call sptlrpc_cli_finish_early_reply() on the returned
1119  * \a *req_ret to release it.
1120  * \retval -ev error number, and \a req_ret will not be set.
1121  */
1122 int sptlrpc_cli_unwrap_early_reply(struct ptlrpc_request *req,
1123                                    struct ptlrpc_request **req_ret)
1124 {
1125         struct ptlrpc_request  *early_req;
1126         char                   *early_buf;
1127         int                     early_bufsz, early_size;
1128         int                     rc;
1129         ENTRY;
1130
1131         early_req = ptlrpc_request_cache_alloc(GFP_NOFS);
1132         if (early_req == NULL)
1133                 RETURN(-ENOMEM);
1134
1135         ptlrpc_cli_req_init(early_req);
1136
1137         early_size = req->rq_nob_received;
1138         early_bufsz = size_roundup_power2(early_size);
1139         OBD_ALLOC_LARGE(early_buf, early_bufsz);
1140         if (early_buf == NULL)
1141                 GOTO(err_req, rc = -ENOMEM);
1142
1143         /* sanity checkings and copy data out, do it inside spinlock */
1144         spin_lock(&req->rq_lock);
1145
1146         if (req->rq_replied) {
1147                 spin_unlock(&req->rq_lock);
1148                 GOTO(err_buf, rc = -EALREADY);
1149         }
1150
1151         LASSERT(req->rq_repbuf);
1152         LASSERT(req->rq_repdata == NULL);
1153         LASSERT(req->rq_repmsg == NULL);
1154
1155         if (req->rq_reply_off != 0) {
1156                 CERROR("early reply with offset %u\n", req->rq_reply_off);
1157                 spin_unlock(&req->rq_lock);
1158                 GOTO(err_buf, rc = -EPROTO);
1159         }
1160
1161         if (req->rq_nob_received != early_size) {
1162                 /* even another early arrived the size should be the same */
1163                 CERROR("data size has changed from %u to %u\n",
1164                        early_size, req->rq_nob_received);
1165                 spin_unlock(&req->rq_lock);
1166                 GOTO(err_buf, rc = -EINVAL);
1167         }
1168
1169         if (req->rq_nob_received < sizeof(struct lustre_msg)) {
1170                 CERROR("early reply length %d too small\n",
1171                        req->rq_nob_received);
1172                 spin_unlock(&req->rq_lock);
1173                 GOTO(err_buf, rc = -EALREADY);
1174         }
1175
1176         memcpy(early_buf, req->rq_repbuf, early_size);
1177         spin_unlock(&req->rq_lock);
1178
1179         early_req->rq_cli_ctx = sptlrpc_cli_ctx_get(req->rq_cli_ctx);
1180         early_req->rq_flvr = req->rq_flvr;
1181         early_req->rq_repbuf = early_buf;
1182         early_req->rq_repbuf_len = early_bufsz;
1183         early_req->rq_repdata = (struct lustre_msg *) early_buf;
1184         early_req->rq_repdata_len = early_size;
1185         early_req->rq_early = 1;
1186         early_req->rq_reqmsg = req->rq_reqmsg;
1187
1188         rc = do_cli_unwrap_reply(early_req);
1189         if (rc) {
1190                 DEBUG_REQ(D_ADAPTTO, early_req,
1191                           "error %d unwrap early reply", rc);
1192                 GOTO(err_ctx, rc);
1193         }
1194
1195         LASSERT(early_req->rq_repmsg);
1196         *req_ret = early_req;
1197         RETURN(0);
1198
1199 err_ctx:
1200         sptlrpc_cli_ctx_put(early_req->rq_cli_ctx, 1);
1201 err_buf:
1202         OBD_FREE_LARGE(early_buf, early_bufsz);
1203 err_req:
1204         ptlrpc_request_cache_free(early_req);
1205         RETURN(rc);
1206 }
1207
1208 /**
1209  * Used by ptlrpc client, to release a processed early reply \a early_req.
1210  *
1211  * \pre \a early_req was obtained from calling sptlrpc_cli_unwrap_early_reply().
1212  */
1213 void sptlrpc_cli_finish_early_reply(struct ptlrpc_request *early_req)
1214 {
1215         LASSERT(early_req->rq_repbuf);
1216         LASSERT(early_req->rq_repdata);
1217         LASSERT(early_req->rq_repmsg);
1218
1219         sptlrpc_cli_ctx_put(early_req->rq_cli_ctx, 1);
1220         OBD_FREE_LARGE(early_req->rq_repbuf, early_req->rq_repbuf_len);
1221         ptlrpc_request_cache_free(early_req);
1222 }
1223
1224 /**************************************************
1225  * sec ID                                         *
1226  **************************************************/
1227
1228 /*
1229  * "fixed" sec (e.g. null) use sec_id < 0
1230  */
1231 static atomic_t sptlrpc_sec_id = ATOMIC_INIT(1);
1232
1233 int sptlrpc_get_next_secid(void)
1234 {
1235         return atomic_inc_return(&sptlrpc_sec_id);
1236 }
1237 EXPORT_SYMBOL(sptlrpc_get_next_secid);
1238
1239 /**************************************************
1240  * client side high-level security APIs           *
1241  **************************************************/
1242
1243 static int sec_cop_flush_ctx_cache(struct ptlrpc_sec *sec, uid_t uid,
1244                                    int grace, int force)
1245 {
1246         struct ptlrpc_sec_policy *policy = sec->ps_policy;
1247
1248         LASSERT(policy->sp_cops);
1249         LASSERT(policy->sp_cops->flush_ctx_cache);
1250
1251         return policy->sp_cops->flush_ctx_cache(sec, uid, grace, force);
1252 }
1253
1254 static void sec_cop_destroy_sec(struct ptlrpc_sec *sec)
1255 {
1256         struct ptlrpc_sec_policy *policy = sec->ps_policy;
1257
1258         LASSERT_ATOMIC_ZERO(&sec->ps_refcount);
1259         LASSERT_ATOMIC_ZERO(&sec->ps_nctx);
1260         LASSERT(policy->sp_cops->destroy_sec);
1261
1262         CDEBUG(D_SEC, "%s@%p: being destroied\n", sec->ps_policy->sp_name, sec);
1263
1264         policy->sp_cops->destroy_sec(sec);
1265         sptlrpc_policy_put(policy);
1266 }
1267
1268 void sptlrpc_sec_destroy(struct ptlrpc_sec *sec)
1269 {
1270         sec_cop_destroy_sec(sec);
1271 }
1272 EXPORT_SYMBOL(sptlrpc_sec_destroy);
1273
1274 static void sptlrpc_sec_kill(struct ptlrpc_sec *sec)
1275 {
1276         LASSERT_ATOMIC_POS(&sec->ps_refcount);
1277
1278         if (sec->ps_policy->sp_cops->kill_sec) {
1279                 sec->ps_policy->sp_cops->kill_sec(sec);
1280
1281                 sec_cop_flush_ctx_cache(sec, -1, 1, 1);
1282         }
1283 }
1284
1285 struct ptlrpc_sec *sptlrpc_sec_get(struct ptlrpc_sec *sec)
1286 {
1287         if (sec)
1288                 atomic_inc(&sec->ps_refcount);
1289
1290         return sec;
1291 }
1292 EXPORT_SYMBOL(sptlrpc_sec_get);
1293
1294 void sptlrpc_sec_put(struct ptlrpc_sec *sec)
1295 {
1296         if (sec) {
1297                 LASSERT_ATOMIC_POS(&sec->ps_refcount);
1298
1299                 if (atomic_dec_and_test(&sec->ps_refcount)) {
1300                         sptlrpc_gc_del_sec(sec);
1301                         sec_cop_destroy_sec(sec);
1302                 }
1303         }
1304 }
1305 EXPORT_SYMBOL(sptlrpc_sec_put);
1306
1307 /*
1308  * policy module is responsible for taking refrence of import
1309  */
1310 static
1311 struct ptlrpc_sec * sptlrpc_sec_create(struct obd_import *imp,
1312                                        struct ptlrpc_svc_ctx *svc_ctx,
1313                                        struct sptlrpc_flavor *sf,
1314                                        enum lustre_sec_part sp)
1315 {
1316         struct ptlrpc_sec_policy *policy;
1317         struct ptlrpc_sec        *sec;
1318         char                      str[32];
1319         ENTRY;
1320
1321         if (svc_ctx) {
1322                 LASSERT(imp->imp_dlm_fake == 1);
1323
1324                 CDEBUG(D_SEC, "%s %s: reverse sec using flavor %s\n",
1325                        imp->imp_obd->obd_type->typ_name,
1326                        imp->imp_obd->obd_name,
1327                        sptlrpc_flavor2name(sf, str, sizeof(str)));
1328
1329                 policy = sptlrpc_policy_get(svc_ctx->sc_policy);
1330                 sf->sf_flags |= PTLRPC_SEC_FL_REVERSE | PTLRPC_SEC_FL_ROOTONLY;
1331         } else {
1332                 LASSERT(imp->imp_dlm_fake == 0);
1333
1334                 CDEBUG(D_SEC, "%s %s: select security flavor %s\n",
1335                        imp->imp_obd->obd_type->typ_name,
1336                        imp->imp_obd->obd_name,
1337                        sptlrpc_flavor2name(sf, str, sizeof(str)));
1338
1339                 policy = sptlrpc_wireflavor2policy(sf->sf_rpc);
1340                 if (!policy) {
1341                         CERROR("invalid flavor 0x%x\n", sf->sf_rpc);
1342                         RETURN(NULL);
1343                 }
1344         }
1345
1346         sec = policy->sp_cops->create_sec(imp, svc_ctx, sf);
1347         if (sec) {
1348                 atomic_inc(&sec->ps_refcount);
1349
1350                 sec->ps_part = sp;
1351
1352                 if (sec->ps_gc_interval && policy->sp_cops->gc_ctx)
1353                         sptlrpc_gc_add_sec(sec);
1354         } else {
1355                 sptlrpc_policy_put(policy);
1356         }
1357
1358         RETURN(sec);
1359 }
1360
1361 struct ptlrpc_sec *sptlrpc_import_sec_ref(struct obd_import *imp)
1362 {
1363         struct ptlrpc_sec *sec;
1364
1365         spin_lock(&imp->imp_lock);
1366         sec = sptlrpc_sec_get(imp->imp_sec);
1367         spin_unlock(&imp->imp_lock);
1368
1369         return sec;
1370 }
1371 EXPORT_SYMBOL(sptlrpc_import_sec_ref);
1372
1373 static void sptlrpc_import_sec_install(struct obd_import *imp,
1374                                        struct ptlrpc_sec *sec)
1375 {
1376         struct ptlrpc_sec *old_sec;
1377
1378         LASSERT_ATOMIC_POS(&sec->ps_refcount);
1379
1380         spin_lock(&imp->imp_lock);
1381         old_sec = imp->imp_sec;
1382         imp->imp_sec = sec;
1383         spin_unlock(&imp->imp_lock);
1384
1385         if (old_sec) {
1386                 sptlrpc_sec_kill(old_sec);
1387
1388                 /* balance the ref taken by this import */
1389                 sptlrpc_sec_put(old_sec);
1390         }
1391 }
1392
1393 static inline
1394 int flavor_equal(struct sptlrpc_flavor *sf1, struct sptlrpc_flavor *sf2)
1395 {
1396         return (memcmp(sf1, sf2, sizeof(*sf1)) == 0);
1397 }
1398
1399 static inline
1400 void flavor_copy(struct sptlrpc_flavor *dst, struct sptlrpc_flavor *src)
1401 {
1402         *dst = *src;
1403 }
1404
1405 static void sptlrpc_import_sec_adapt_inplace(struct obd_import *imp,
1406                                              struct ptlrpc_sec *sec,
1407                                              struct sptlrpc_flavor *sf)
1408 {
1409         char    str1[32], str2[32];
1410
1411         if (sec->ps_flvr.sf_flags != sf->sf_flags)
1412                 CDEBUG(D_SEC, "changing sec flags: %s -> %s\n",
1413                        sptlrpc_secflags2str(sec->ps_flvr.sf_flags,
1414                                             str1, sizeof(str1)),
1415                        sptlrpc_secflags2str(sf->sf_flags,
1416                                             str2, sizeof(str2)));
1417
1418         spin_lock(&sec->ps_lock);
1419         flavor_copy(&sec->ps_flvr, sf);
1420         spin_unlock(&sec->ps_lock);
1421 }
1422
1423 /**
1424  * To get an appropriate ptlrpc_sec for the \a imp, according to the current
1425  * configuration. Upon called, imp->imp_sec may or may not be NULL.
1426  *
1427  *  - regular import: \a svc_ctx should be NULL and \a flvr is ignored;
1428  *  - reverse import: \a svc_ctx and \a flvr are obtained from incoming request.
1429  */
1430 int sptlrpc_import_sec_adapt(struct obd_import *imp,
1431                              struct ptlrpc_svc_ctx *svc_ctx,
1432                              struct sptlrpc_flavor *flvr)
1433 {
1434         struct ptlrpc_connection   *conn;
1435         struct sptlrpc_flavor       sf;
1436         struct ptlrpc_sec          *sec, *newsec;
1437         enum lustre_sec_part        sp;
1438         char                        str[24];
1439         int                         rc = 0;
1440         ENTRY;
1441
1442         might_sleep();
1443
1444         if (imp == NULL)
1445                 RETURN(0);
1446
1447         conn = imp->imp_connection;
1448
1449         if (svc_ctx == NULL) {
1450                 struct client_obd *cliobd = &imp->imp_obd->u.cli;
1451                 /*
1452                  * normal import, determine flavor from rule set, except
1453                  * for mgc the flavor is predetermined.
1454                  */
1455                 if (cliobd->cl_sp_me == LUSTRE_SP_MGC)
1456                         sf = cliobd->cl_flvr_mgc;
1457                 else 
1458                         sptlrpc_conf_choose_flavor(cliobd->cl_sp_me,
1459                                                    cliobd->cl_sp_to,
1460                                                    &cliobd->cl_target_uuid,
1461                                                    conn->c_self, &sf);
1462
1463                 sp = imp->imp_obd->u.cli.cl_sp_me;
1464         } else {
1465                 /* reverse import, determine flavor from incoming reqeust */
1466                 sf = *flvr;
1467
1468                 if (sf.sf_rpc != SPTLRPC_FLVR_NULL)
1469                         sf.sf_flags = PTLRPC_SEC_FL_REVERSE |
1470                                       PTLRPC_SEC_FL_ROOTONLY;
1471
1472                 sp = sptlrpc_target_sec_part(imp->imp_obd);
1473         }
1474
1475         sec = sptlrpc_import_sec_ref(imp);
1476         if (sec) {
1477                 char    str2[24];
1478
1479                 if (flavor_equal(&sf, &sec->ps_flvr))
1480                         GOTO(out, rc);
1481
1482                 CDEBUG(D_SEC, "import %s->%s: changing flavor %s -> %s\n",
1483                        imp->imp_obd->obd_name,
1484                        obd_uuid2str(&conn->c_remote_uuid),
1485                        sptlrpc_flavor2name(&sec->ps_flvr, str, sizeof(str)),
1486                        sptlrpc_flavor2name(&sf, str2, sizeof(str2)));
1487
1488                 if (SPTLRPC_FLVR_POLICY(sf.sf_rpc) ==
1489                     SPTLRPC_FLVR_POLICY(sec->ps_flvr.sf_rpc) &&
1490                     SPTLRPC_FLVR_MECH(sf.sf_rpc) ==
1491                     SPTLRPC_FLVR_MECH(sec->ps_flvr.sf_rpc)) {
1492                         sptlrpc_import_sec_adapt_inplace(imp, sec, &sf);
1493                         GOTO(out, rc);
1494                 }
1495         } else if (SPTLRPC_FLVR_BASE(sf.sf_rpc) !=
1496                    SPTLRPC_FLVR_BASE(SPTLRPC_FLVR_NULL)) {
1497                 CDEBUG(D_SEC, "import %s->%s netid %x: select flavor %s\n",
1498                        imp->imp_obd->obd_name,
1499                        obd_uuid2str(&conn->c_remote_uuid),
1500                        LNET_NIDNET(conn->c_self),
1501                        sptlrpc_flavor2name(&sf, str, sizeof(str)));
1502         }
1503
1504         mutex_lock(&imp->imp_sec_mutex);
1505
1506         newsec = sptlrpc_sec_create(imp, svc_ctx, &sf, sp);
1507         if (newsec) {
1508                 sptlrpc_import_sec_install(imp, newsec);
1509         } else {
1510                 CERROR("import %s->%s: failed to create new sec\n",
1511                        imp->imp_obd->obd_name,
1512                        obd_uuid2str(&conn->c_remote_uuid));
1513                 rc = -EPERM;
1514         }
1515
1516         mutex_unlock(&imp->imp_sec_mutex);
1517 out:
1518         sptlrpc_sec_put(sec);
1519         RETURN(rc);
1520 }
1521
1522 void sptlrpc_import_sec_put(struct obd_import *imp)
1523 {
1524         if (imp->imp_sec) {
1525                 sptlrpc_sec_kill(imp->imp_sec);
1526
1527                 sptlrpc_sec_put(imp->imp_sec);
1528                 imp->imp_sec = NULL;
1529         }
1530 }
1531
1532 static void import_flush_ctx_common(struct obd_import *imp,
1533                                     uid_t uid, int grace, int force)
1534 {
1535         struct ptlrpc_sec *sec;
1536
1537         if (imp == NULL)
1538                 return;
1539
1540         sec = sptlrpc_import_sec_ref(imp);
1541         if (sec == NULL)
1542                 return;
1543
1544         sec_cop_flush_ctx_cache(sec, uid, grace, force);
1545         sptlrpc_sec_put(sec);
1546 }
1547
1548 void sptlrpc_import_flush_root_ctx(struct obd_import *imp)
1549 {
1550         /* it's important to use grace mode, see explain in
1551          * sptlrpc_req_refresh_ctx() */
1552         import_flush_ctx_common(imp, 0, 1, 1);
1553 }
1554
1555 void sptlrpc_import_flush_my_ctx(struct obd_import *imp)
1556 {
1557         import_flush_ctx_common(imp, from_kuid(&init_user_ns, current_uid()),
1558                                 1, 1);
1559 }
1560 EXPORT_SYMBOL(sptlrpc_import_flush_my_ctx);
1561
1562 void sptlrpc_import_flush_all_ctx(struct obd_import *imp)
1563 {
1564         import_flush_ctx_common(imp, -1, 1, 1);
1565 }
1566 EXPORT_SYMBOL(sptlrpc_import_flush_all_ctx);
1567
1568 /**
1569  * Used by ptlrpc client to allocate request buffer of \a req. Upon return
1570  * successfully, req->rq_reqmsg points to a buffer with size \a msgsize.
1571  */
1572 int sptlrpc_cli_alloc_reqbuf(struct ptlrpc_request *req, int msgsize)
1573 {
1574         struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx;
1575         struct ptlrpc_sec_policy *policy;
1576         int rc;
1577
1578         LASSERT(ctx);
1579         LASSERT(ctx->cc_sec);
1580         LASSERT(ctx->cc_sec->ps_policy);
1581         LASSERT(req->rq_reqmsg == NULL);
1582         LASSERT_ATOMIC_POS(&ctx->cc_refcount);
1583
1584         policy = ctx->cc_sec->ps_policy;
1585         rc = policy->sp_cops->alloc_reqbuf(ctx->cc_sec, req, msgsize);
1586         if (!rc) {
1587                 LASSERT(req->rq_reqmsg);
1588                 LASSERT(req->rq_reqbuf || req->rq_clrbuf);
1589
1590                 /* zeroing preallocated buffer */
1591                 if (req->rq_pool)
1592                         memset(req->rq_reqmsg, 0, msgsize);
1593         }
1594
1595         return rc;
1596 }
1597
1598 /**
1599  * Used by ptlrpc client to free request buffer of \a req. After this
1600  * req->rq_reqmsg is set to NULL and should not be accessed anymore.
1601  */
1602 void sptlrpc_cli_free_reqbuf(struct ptlrpc_request *req)
1603 {
1604         struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx;
1605         struct ptlrpc_sec_policy *policy;
1606
1607         LASSERT(ctx);
1608         LASSERT(ctx->cc_sec);
1609         LASSERT(ctx->cc_sec->ps_policy);
1610         LASSERT_ATOMIC_POS(&ctx->cc_refcount);
1611
1612         if (req->rq_reqbuf == NULL && req->rq_clrbuf == NULL)
1613                 return;
1614
1615         policy = ctx->cc_sec->ps_policy;
1616         policy->sp_cops->free_reqbuf(ctx->cc_sec, req);
1617         req->rq_reqmsg = NULL;
1618 }
1619
1620 /*
1621  * NOTE caller must guarantee the buffer size is enough for the enlargement
1622  */
1623 void _sptlrpc_enlarge_msg_inplace(struct lustre_msg *msg,
1624                                   int segment, int newsize)
1625 {
1626         void   *src, *dst;
1627         int     oldsize, oldmsg_size, movesize;
1628
1629         LASSERT(segment < msg->lm_bufcount);
1630         LASSERT(msg->lm_buflens[segment] <= newsize);
1631
1632         if (msg->lm_buflens[segment] == newsize)
1633                 return;
1634
1635         /* nothing to do if we are enlarging the last segment */
1636         if (segment == msg->lm_bufcount - 1) {
1637                 msg->lm_buflens[segment] = newsize;
1638                 return;
1639         }
1640
1641         oldsize = msg->lm_buflens[segment];
1642
1643         src = lustre_msg_buf(msg, segment + 1, 0);
1644         msg->lm_buflens[segment] = newsize;
1645         dst = lustre_msg_buf(msg, segment + 1, 0);
1646         msg->lm_buflens[segment] = oldsize;
1647
1648         /* move from segment + 1 to end segment */
1649         LASSERT(msg->lm_magic == LUSTRE_MSG_MAGIC_V2);
1650         oldmsg_size = lustre_msg_size_v2(msg->lm_bufcount, msg->lm_buflens);
1651         movesize = oldmsg_size - ((unsigned long) src - (unsigned long) msg);
1652         LASSERT(movesize >= 0);
1653
1654         if (movesize)
1655                 memmove(dst, src, movesize);
1656
1657         /* note we don't clear the ares where old data live, not secret */
1658
1659         /* finally set new segment size */
1660         msg->lm_buflens[segment] = newsize;
1661 }
1662 EXPORT_SYMBOL(_sptlrpc_enlarge_msg_inplace);
1663
1664 /**
1665  * Used by ptlrpc client to enlarge the \a segment of request message pointed
1666  * by req->rq_reqmsg to size \a newsize, all previously filled-in data will be
1667  * preserved after the enlargement. this must be called after original request
1668  * buffer being allocated.
1669  *
1670  * \note after this be called, rq_reqmsg and rq_reqlen might have been changed,
1671  * so caller should refresh its local pointers if needed.
1672  */
1673 int sptlrpc_cli_enlarge_reqbuf(struct ptlrpc_request *req,
1674                                int segment, int newsize)
1675 {
1676         struct ptlrpc_cli_ctx    *ctx = req->rq_cli_ctx;
1677         struct ptlrpc_sec_cops   *cops;
1678         struct lustre_msg        *msg = req->rq_reqmsg;
1679
1680         LASSERT(ctx);
1681         LASSERT(msg);
1682         LASSERT(msg->lm_bufcount > segment);
1683         LASSERT(msg->lm_buflens[segment] <= newsize);
1684
1685         if (msg->lm_buflens[segment] == newsize)
1686                 return 0;
1687
1688         cops = ctx->cc_sec->ps_policy->sp_cops;
1689         LASSERT(cops->enlarge_reqbuf);
1690         return cops->enlarge_reqbuf(ctx->cc_sec, req, segment, newsize);
1691 }
1692 EXPORT_SYMBOL(sptlrpc_cli_enlarge_reqbuf);
1693
1694 /**
1695  * Used by ptlrpc client to allocate reply buffer of \a req.
1696  *
1697  * \note After this, req->rq_repmsg is still not accessible.
1698  */
1699 int sptlrpc_cli_alloc_repbuf(struct ptlrpc_request *req, int msgsize)
1700 {
1701         struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx;
1702         struct ptlrpc_sec_policy *policy;
1703         ENTRY;
1704
1705         LASSERT(ctx);
1706         LASSERT(ctx->cc_sec);
1707         LASSERT(ctx->cc_sec->ps_policy);
1708
1709         if (req->rq_repbuf)
1710                 RETURN(0);
1711
1712         policy = ctx->cc_sec->ps_policy;
1713         RETURN(policy->sp_cops->alloc_repbuf(ctx->cc_sec, req, msgsize));
1714 }
1715
1716 /**
1717  * Used by ptlrpc client to free reply buffer of \a req. After this
1718  * req->rq_repmsg is set to NULL and should not be accessed anymore.
1719  */
1720 void sptlrpc_cli_free_repbuf(struct ptlrpc_request *req)
1721 {
1722         struct ptlrpc_cli_ctx *ctx = req->rq_cli_ctx;
1723         struct ptlrpc_sec_policy *policy;
1724         ENTRY;
1725
1726         LASSERT(ctx);
1727         LASSERT(ctx->cc_sec);
1728         LASSERT(ctx->cc_sec->ps_policy);
1729         LASSERT_ATOMIC_POS(&ctx->cc_refcount);
1730
1731         if (req->rq_repbuf == NULL)
1732                 return;
1733         LASSERT(req->rq_repbuf_len);
1734
1735         policy = ctx->cc_sec->ps_policy;
1736         policy->sp_cops->free_repbuf(ctx->cc_sec, req);
1737         req->rq_repmsg = NULL;
1738         EXIT;
1739 }
1740
1741 int sptlrpc_cli_install_rvs_ctx(struct obd_import *imp,
1742                                 struct ptlrpc_cli_ctx *ctx)
1743 {
1744         struct ptlrpc_sec_policy *policy = ctx->cc_sec->ps_policy;
1745
1746         if (!policy->sp_cops->install_rctx)
1747                 return 0;
1748         return policy->sp_cops->install_rctx(imp, ctx->cc_sec, ctx);
1749 }
1750
1751 int sptlrpc_svc_install_rvs_ctx(struct obd_import *imp,
1752                                 struct ptlrpc_svc_ctx *ctx)
1753 {
1754         struct ptlrpc_sec_policy *policy = ctx->sc_policy;
1755
1756         if (!policy->sp_sops->install_rctx)
1757                 return 0;
1758         return policy->sp_sops->install_rctx(imp, ctx);
1759 }
1760
1761 /****************************************
1762  * server side security                 *
1763  ****************************************/
1764
1765 static int flavor_allowed(struct sptlrpc_flavor *exp,
1766                           struct ptlrpc_request *req)
1767 {
1768         struct sptlrpc_flavor *flvr = &req->rq_flvr;
1769
1770         if (exp->sf_rpc == SPTLRPC_FLVR_ANY || exp->sf_rpc == flvr->sf_rpc)
1771                 return 1;
1772
1773         if ((req->rq_ctx_init || req->rq_ctx_fini) &&
1774             SPTLRPC_FLVR_POLICY(exp->sf_rpc) ==
1775             SPTLRPC_FLVR_POLICY(flvr->sf_rpc) &&
1776             SPTLRPC_FLVR_MECH(exp->sf_rpc) == SPTLRPC_FLVR_MECH(flvr->sf_rpc))
1777                 return 1;
1778
1779         return 0;
1780 }
1781
1782 #define EXP_FLVR_UPDATE_EXPIRE      (OBD_TIMEOUT_DEFAULT + 10)
1783
1784 /**
1785  * Given an export \a exp, check whether the flavor of incoming \a req
1786  * is allowed by the export \a exp. Main logic is about taking care of
1787  * changing configurations. Return 0 means success.
1788  */
1789 int sptlrpc_target_export_check(struct obd_export *exp,
1790                                 struct ptlrpc_request *req)
1791 {
1792         struct sptlrpc_flavor   flavor;
1793
1794         if (exp == NULL)
1795                 return 0;
1796
1797         /* client side export has no imp_reverse, skip
1798          * FIXME maybe we should check flavor this as well??? */
1799         if (exp->exp_imp_reverse == NULL)
1800                 return 0;
1801
1802         /* don't care about ctx fini rpc */
1803         if (req->rq_ctx_fini)
1804                 return 0;
1805
1806         spin_lock(&exp->exp_lock);
1807
1808         /* if flavor just changed (exp->exp_flvr_changed != 0), we wait for
1809          * the first req with the new flavor, then treat it as current flavor,
1810          * adapt reverse sec according to it.
1811          * note the first rpc with new flavor might not be with root ctx, in
1812          * which case delay the sec_adapt by leaving exp_flvr_adapt == 1. */
1813         if (unlikely(exp->exp_flvr_changed) &&
1814             flavor_allowed(&exp->exp_flvr_old[1], req)) {
1815                 /* make the new flavor as "current", and old ones as
1816                  * about-to-expire */
1817                 CDEBUG(D_SEC, "exp %p: just changed: %x->%x\n", exp,
1818                        exp->exp_flvr.sf_rpc, exp->exp_flvr_old[1].sf_rpc);
1819                 flavor = exp->exp_flvr_old[1];
1820                 exp->exp_flvr_old[1] = exp->exp_flvr_old[0];
1821                 exp->exp_flvr_expire[1] = exp->exp_flvr_expire[0];
1822                 exp->exp_flvr_old[0] = exp->exp_flvr;
1823                 exp->exp_flvr_expire[0] = cfs_time_current_sec() +
1824                                           EXP_FLVR_UPDATE_EXPIRE;
1825                 exp->exp_flvr = flavor;
1826
1827                 /* flavor change finished */
1828                 exp->exp_flvr_changed = 0;
1829                 LASSERT(exp->exp_flvr_adapt == 1);
1830
1831                 /* if it's gss, we only interested in root ctx init */
1832                 if (req->rq_auth_gss &&
1833                     !(req->rq_ctx_init &&
1834                       (req->rq_auth_usr_root || req->rq_auth_usr_mdt ||
1835                        req->rq_auth_usr_ost))) {
1836                         spin_unlock(&exp->exp_lock);
1837                         CDEBUG(D_SEC, "is good but not root(%d:%d:%d:%d:%d)\n",
1838                                req->rq_auth_gss, req->rq_ctx_init,
1839                                req->rq_auth_usr_root, req->rq_auth_usr_mdt,
1840                                req->rq_auth_usr_ost);
1841                         return 0;
1842                 }
1843
1844                 exp->exp_flvr_adapt = 0;
1845                 spin_unlock(&exp->exp_lock);
1846
1847                 return sptlrpc_import_sec_adapt(exp->exp_imp_reverse,
1848                                                 req->rq_svc_ctx, &flavor);
1849         }
1850
1851         /* if it equals to the current flavor, we accept it, but need to
1852          * dealing with reverse sec/ctx */
1853         if (likely(flavor_allowed(&exp->exp_flvr, req))) {
1854                 /* most cases should return here, we only interested in
1855                  * gss root ctx init */
1856                 if (!req->rq_auth_gss || !req->rq_ctx_init ||
1857                     (!req->rq_auth_usr_root && !req->rq_auth_usr_mdt &&
1858                      !req->rq_auth_usr_ost)) {
1859                         spin_unlock(&exp->exp_lock);
1860                         return 0;
1861                 }
1862
1863                 /* if flavor just changed, we should not proceed, just leave
1864                  * it and current flavor will be discovered and replaced
1865                  * shortly, and let _this_ rpc pass through */
1866                 if (exp->exp_flvr_changed) {
1867                         LASSERT(exp->exp_flvr_adapt);
1868                         spin_unlock(&exp->exp_lock);
1869                         return 0;
1870                 }
1871
1872                 if (exp->exp_flvr_adapt) {
1873                         exp->exp_flvr_adapt = 0;
1874                         CDEBUG(D_SEC, "exp %p (%x|%x|%x): do delayed adapt\n",
1875                                exp, exp->exp_flvr.sf_rpc,
1876                                exp->exp_flvr_old[0].sf_rpc,
1877                                exp->exp_flvr_old[1].sf_rpc);
1878                         flavor = exp->exp_flvr;
1879                         spin_unlock(&exp->exp_lock);
1880
1881                         return sptlrpc_import_sec_adapt(exp->exp_imp_reverse,
1882                                                         req->rq_svc_ctx,
1883                                                         &flavor);
1884                 } else {
1885                         CDEBUG(D_SEC, "exp %p (%x|%x|%x): is current flavor, "
1886                                "install rvs ctx\n", exp, exp->exp_flvr.sf_rpc,
1887                                exp->exp_flvr_old[0].sf_rpc,
1888                                exp->exp_flvr_old[1].sf_rpc);
1889                         spin_unlock(&exp->exp_lock);
1890
1891                         return sptlrpc_svc_install_rvs_ctx(exp->exp_imp_reverse,
1892                                                            req->rq_svc_ctx);
1893                 }
1894         }
1895
1896         if (exp->exp_flvr_expire[0]) {
1897                 if (exp->exp_flvr_expire[0] >= cfs_time_current_sec()) {
1898                         if (flavor_allowed(&exp->exp_flvr_old[0], req)) {
1899                                 CDEBUG(D_SEC, "exp %p (%x|%x|%x): match the "
1900                                        "middle one ("CFS_DURATION_T")\n", exp,
1901                                        exp->exp_flvr.sf_rpc,
1902                                        exp->exp_flvr_old[0].sf_rpc,
1903                                        exp->exp_flvr_old[1].sf_rpc,
1904                                        exp->exp_flvr_expire[0] -
1905                                                 cfs_time_current_sec());
1906                                 spin_unlock(&exp->exp_lock);
1907                                 return 0;
1908                         }
1909                 } else {
1910                         CDEBUG(D_SEC, "mark middle expired\n");
1911                         exp->exp_flvr_expire[0] = 0;
1912                 }
1913                 CDEBUG(D_SEC, "exp %p (%x|%x|%x): %x not match middle\n", exp,
1914                        exp->exp_flvr.sf_rpc,
1915                        exp->exp_flvr_old[0].sf_rpc, exp->exp_flvr_old[1].sf_rpc,
1916                        req->rq_flvr.sf_rpc);
1917         }
1918
1919         /* now it doesn't match the current flavor, the only chance we can
1920          * accept it is match the old flavors which is not expired. */
1921         if (exp->exp_flvr_changed == 0 && exp->exp_flvr_expire[1]) {
1922                 if (exp->exp_flvr_expire[1] >= cfs_time_current_sec()) {
1923                         if (flavor_allowed(&exp->exp_flvr_old[1], req)) {
1924                                 CDEBUG(D_SEC, "exp %p (%x|%x|%x): match the "
1925                                        "oldest one ("CFS_DURATION_T")\n", exp,
1926                                        exp->exp_flvr.sf_rpc,
1927                                        exp->exp_flvr_old[0].sf_rpc,
1928                                        exp->exp_flvr_old[1].sf_rpc,
1929                                        exp->exp_flvr_expire[1] -
1930                                                 cfs_time_current_sec());
1931                                 spin_unlock(&exp->exp_lock);
1932                                 return 0;
1933                         }
1934                 } else {
1935                         CDEBUG(D_SEC, "mark oldest expired\n");
1936                         exp->exp_flvr_expire[1] = 0;
1937                 }
1938                 CDEBUG(D_SEC, "exp %p (%x|%x|%x): %x not match found\n",
1939                        exp, exp->exp_flvr.sf_rpc,
1940                        exp->exp_flvr_old[0].sf_rpc, exp->exp_flvr_old[1].sf_rpc,
1941                        req->rq_flvr.sf_rpc);
1942         } else {
1943                 CDEBUG(D_SEC, "exp %p (%x|%x|%x): skip the last one\n",
1944                        exp, exp->exp_flvr.sf_rpc, exp->exp_flvr_old[0].sf_rpc,
1945                        exp->exp_flvr_old[1].sf_rpc);
1946         }
1947
1948         spin_unlock(&exp->exp_lock);
1949
1950         CWARN("exp %p(%s): req %p (%u|%u|%u|%u|%u|%u) with "
1951               "unauthorized flavor %x, expect %x|%x(%+ld)|%x(%+ld)\n",
1952               exp, exp->exp_obd->obd_name,
1953               req, req->rq_auth_gss, req->rq_ctx_init, req->rq_ctx_fini,
1954               req->rq_auth_usr_root, req->rq_auth_usr_mdt, req->rq_auth_usr_ost,
1955               req->rq_flvr.sf_rpc,
1956               exp->exp_flvr.sf_rpc,
1957               exp->exp_flvr_old[0].sf_rpc,
1958               exp->exp_flvr_expire[0] ?
1959               (unsigned long) (exp->exp_flvr_expire[0] -
1960                                cfs_time_current_sec()) : 0,
1961               exp->exp_flvr_old[1].sf_rpc,
1962               exp->exp_flvr_expire[1] ?
1963               (unsigned long) (exp->exp_flvr_expire[1] -
1964                                cfs_time_current_sec()) : 0);
1965         return -EACCES;
1966 }
1967 EXPORT_SYMBOL(sptlrpc_target_export_check);
1968
1969 void sptlrpc_target_update_exp_flavor(struct obd_device *obd,
1970                                       struct sptlrpc_rule_set *rset)
1971 {
1972         struct obd_export       *exp;
1973         struct sptlrpc_flavor    new_flvr;
1974
1975         LASSERT(obd);
1976
1977         spin_lock(&obd->obd_dev_lock);
1978
1979         list_for_each_entry(exp, &obd->obd_exports, exp_obd_chain) {
1980                 if (exp->exp_connection == NULL)
1981                         continue;
1982
1983                 /* note if this export had just been updated flavor
1984                  * (exp_flvr_changed == 1), this will override the
1985                  * previous one. */
1986                 spin_lock(&exp->exp_lock);
1987                 sptlrpc_target_choose_flavor(rset, exp->exp_sp_peer,
1988                                              exp->exp_connection->c_peer.nid,
1989                                              &new_flvr);
1990                 if (exp->exp_flvr_changed ||
1991                     !flavor_equal(&new_flvr, &exp->exp_flvr)) {
1992                         exp->exp_flvr_old[1] = new_flvr;
1993                         exp->exp_flvr_expire[1] = 0;
1994                         exp->exp_flvr_changed = 1;
1995                         exp->exp_flvr_adapt = 1;
1996
1997                         CDEBUG(D_SEC, "exp %p (%s): updated flavor %x->%x\n",
1998                                exp, sptlrpc_part2name(exp->exp_sp_peer),
1999                                exp->exp_flvr.sf_rpc,
2000                                exp->exp_flvr_old[1].sf_rpc);
2001                 }
2002                 spin_unlock(&exp->exp_lock);
2003         }
2004
2005         spin_unlock(&obd->obd_dev_lock);
2006 }
2007 EXPORT_SYMBOL(sptlrpc_target_update_exp_flavor);
2008
2009 static int sptlrpc_svc_check_from(struct ptlrpc_request *req, int svc_rc)
2010 {
2011         /* peer's claim is unreliable unless gss is being used */
2012         if (!req->rq_auth_gss || svc_rc == SECSVC_DROP)
2013                 return svc_rc;
2014
2015         switch (req->rq_sp_from) {
2016         case LUSTRE_SP_CLI:
2017                 if (req->rq_auth_usr_mdt || req->rq_auth_usr_ost) {
2018                         DEBUG_REQ(D_ERROR, req, "faked source CLI");
2019                         svc_rc = SECSVC_DROP;
2020                 }
2021                 break;
2022         case LUSTRE_SP_MDT:
2023                 if (!req->rq_auth_usr_mdt) {
2024                         DEBUG_REQ(D_ERROR, req, "faked source MDT");
2025                         svc_rc = SECSVC_DROP;
2026                 }
2027                 break;
2028         case LUSTRE_SP_OST:
2029                 if (!req->rq_auth_usr_ost) {
2030                         DEBUG_REQ(D_ERROR, req, "faked source OST");
2031                         svc_rc = SECSVC_DROP;
2032                 }
2033                 break;
2034         case LUSTRE_SP_MGS:
2035         case LUSTRE_SP_MGC:
2036                 if (!req->rq_auth_usr_root && !req->rq_auth_usr_mdt &&
2037                     !req->rq_auth_usr_ost) {
2038                         DEBUG_REQ(D_ERROR, req, "faked source MGC/MGS");
2039                         svc_rc = SECSVC_DROP;
2040                 }
2041                 break;
2042         case LUSTRE_SP_ANY:
2043         default:
2044                 DEBUG_REQ(D_ERROR, req, "invalid source %u", req->rq_sp_from);
2045                 svc_rc = SECSVC_DROP;
2046         }
2047
2048         return svc_rc;
2049 }
2050
2051 /**
2052  * Used by ptlrpc server, to perform transformation upon request message of
2053  * incoming \a req. This must be the first thing to do with an incoming
2054  * request in ptlrpc layer.
2055  *
2056  * \retval SECSVC_OK success, and req->rq_reqmsg point to request message in
2057  * clear text, size is req->rq_reqlen; also req->rq_svc_ctx is set.
2058  * \retval SECSVC_COMPLETE success, the request has been fully processed, and
2059  * reply message has been prepared.
2060  * \retval SECSVC_DROP failed, this request should be dropped.
2061  */
2062 int sptlrpc_svc_unwrap_request(struct ptlrpc_request *req)
2063 {
2064         struct ptlrpc_sec_policy *policy;
2065         struct lustre_msg        *msg = req->rq_reqbuf;
2066         int                       rc;
2067         ENTRY;
2068
2069         LASSERT(msg);
2070         LASSERT(req->rq_reqmsg == NULL);
2071         LASSERT(req->rq_repmsg == NULL);
2072         LASSERT(req->rq_svc_ctx == NULL);
2073
2074         req->rq_req_swab_mask = 0;
2075
2076         rc = __lustre_unpack_msg(msg, req->rq_reqdata_len);
2077         switch (rc) {
2078         case 1:
2079                 lustre_set_req_swabbed(req, MSG_PTLRPC_HEADER_OFF);
2080         case 0:
2081                 break;
2082         default:
2083                 CERROR("error unpacking request from %s x"LPU64"\n",
2084                        libcfs_id2str(req->rq_peer), req->rq_xid);
2085                 RETURN(SECSVC_DROP);
2086         }
2087
2088         req->rq_flvr.sf_rpc = WIRE_FLVR(msg->lm_secflvr);
2089         req->rq_sp_from = LUSTRE_SP_ANY;
2090         req->rq_auth_uid = -1;          /* set to INVALID_UID */
2091         req->rq_auth_mapped_uid = -1;
2092
2093         policy = sptlrpc_wireflavor2policy(req->rq_flvr.sf_rpc);
2094         if (!policy) {
2095                 CERROR("unsupported rpc flavor %x\n", req->rq_flvr.sf_rpc);
2096                 RETURN(SECSVC_DROP);
2097         }
2098
2099         LASSERT(policy->sp_sops->accept);
2100         rc = policy->sp_sops->accept(req);
2101         sptlrpc_policy_put(policy);
2102         LASSERT(req->rq_reqmsg || rc != SECSVC_OK);
2103         LASSERT(req->rq_svc_ctx || rc == SECSVC_DROP);
2104
2105         /*
2106          * if it's not null flavor (which means embedded packing msg),
2107          * reset the swab mask for the comming inner msg unpacking.
2108          */
2109         if (SPTLRPC_FLVR_POLICY(req->rq_flvr.sf_rpc) != SPTLRPC_POLICY_NULL)
2110                 req->rq_req_swab_mask = 0;
2111
2112         /* sanity check for the request source */
2113         rc = sptlrpc_svc_check_from(req, rc);
2114         RETURN(rc);
2115 }
2116
2117 /**
2118  * Used by ptlrpc server, to allocate reply buffer for \a req. If succeed,
2119  * req->rq_reply_state is set, and req->rq_reply_state->rs_msg point to
2120  * a buffer of \a msglen size.
2121  */
2122 int sptlrpc_svc_alloc_rs(struct ptlrpc_request *req, int msglen)
2123 {
2124         struct ptlrpc_sec_policy *policy;
2125         struct ptlrpc_reply_state *rs;
2126         int rc;
2127         ENTRY;
2128
2129         LASSERT(req->rq_svc_ctx);
2130         LASSERT(req->rq_svc_ctx->sc_policy);
2131
2132         policy = req->rq_svc_ctx->sc_policy;
2133         LASSERT(policy->sp_sops->alloc_rs);
2134
2135         rc = policy->sp_sops->alloc_rs(req, msglen);
2136         if (unlikely(rc == -ENOMEM)) {
2137                 struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt;
2138                 if (svcpt->scp_service->srv_max_reply_size <
2139                    msglen + sizeof(struct ptlrpc_reply_state)) {
2140                         /* Just return failure if the size is too big */
2141                         CERROR("size of message is too big (%zd), %d allowed\n",
2142                                 msglen + sizeof(struct ptlrpc_reply_state),
2143                                 svcpt->scp_service->srv_max_reply_size);
2144                         RETURN(-ENOMEM);
2145                 }
2146
2147                 /* failed alloc, try emergency pool */
2148                 rs = lustre_get_emerg_rs(svcpt);
2149                 if (rs == NULL)
2150                         RETURN(-ENOMEM);
2151
2152                 req->rq_reply_state = rs;
2153                 rc = policy->sp_sops->alloc_rs(req, msglen);
2154                 if (rc) {
2155                         lustre_put_emerg_rs(rs);
2156                         req->rq_reply_state = NULL;
2157                 }
2158         }
2159
2160         LASSERT(rc != 0 ||
2161                 (req->rq_reply_state && req->rq_reply_state->rs_msg));
2162
2163         RETURN(rc);
2164 }
2165
2166 /**
2167  * Used by ptlrpc server, to perform transformation upon reply message.
2168  *
2169  * \post req->rq_reply_off is set to approriate server-controlled reply offset.
2170  * \post req->rq_repmsg and req->rq_reply_state->rs_msg becomes inaccessible.
2171  */
2172 int sptlrpc_svc_wrap_reply(struct ptlrpc_request *req)
2173 {
2174         struct ptlrpc_sec_policy *policy;
2175         int rc;
2176         ENTRY;
2177
2178         LASSERT(req->rq_svc_ctx);
2179         LASSERT(req->rq_svc_ctx->sc_policy);
2180
2181         policy = req->rq_svc_ctx->sc_policy;
2182         LASSERT(policy->sp_sops->authorize);
2183
2184         rc = policy->sp_sops->authorize(req);
2185         LASSERT(rc || req->rq_reply_state->rs_repdata_len);
2186
2187         RETURN(rc);
2188 }
2189
2190 /**
2191  * Used by ptlrpc server, to free reply_state.
2192  */
2193 void sptlrpc_svc_free_rs(struct ptlrpc_reply_state *rs)
2194 {
2195         struct ptlrpc_sec_policy *policy;
2196         unsigned int prealloc;
2197         ENTRY;
2198
2199         LASSERT(rs->rs_svc_ctx);
2200         LASSERT(rs->rs_svc_ctx->sc_policy);
2201
2202         policy = rs->rs_svc_ctx->sc_policy;
2203         LASSERT(policy->sp_sops->free_rs);
2204
2205         prealloc = rs->rs_prealloc;
2206         policy->sp_sops->free_rs(rs);
2207
2208         if (prealloc)
2209                 lustre_put_emerg_rs(rs);
2210         EXIT;
2211 }
2212
2213 void sptlrpc_svc_ctx_addref(struct ptlrpc_request *req)
2214 {
2215         struct ptlrpc_svc_ctx *ctx = req->rq_svc_ctx;
2216
2217         if (ctx != NULL)
2218                 atomic_inc(&ctx->sc_refcount);
2219 }
2220
2221 void sptlrpc_svc_ctx_decref(struct ptlrpc_request *req)
2222 {
2223         struct ptlrpc_svc_ctx *ctx = req->rq_svc_ctx;
2224
2225         if (ctx == NULL)
2226                 return;
2227
2228         LASSERT_ATOMIC_POS(&ctx->sc_refcount);
2229         if (atomic_dec_and_test(&ctx->sc_refcount)) {
2230                 if (ctx->sc_policy->sp_sops->free_ctx)
2231                         ctx->sc_policy->sp_sops->free_ctx(ctx);
2232         }
2233         req->rq_svc_ctx = NULL;
2234 }
2235
2236 void sptlrpc_svc_ctx_invalidate(struct ptlrpc_request *req)
2237 {
2238         struct ptlrpc_svc_ctx *ctx = req->rq_svc_ctx;
2239
2240         if (ctx == NULL)
2241                 return;
2242
2243         LASSERT_ATOMIC_POS(&ctx->sc_refcount);
2244         if (ctx->sc_policy->sp_sops->invalidate_ctx)
2245                 ctx->sc_policy->sp_sops->invalidate_ctx(ctx);
2246 }
2247 EXPORT_SYMBOL(sptlrpc_svc_ctx_invalidate);
2248
2249 /****************************************
2250  * bulk security                        *
2251  ****************************************/
2252
2253 /**
2254  * Perform transformation upon bulk data pointed by \a desc. This is called
2255  * before transforming the request message.
2256  */
2257 int sptlrpc_cli_wrap_bulk(struct ptlrpc_request *req,
2258                           struct ptlrpc_bulk_desc *desc)
2259 {
2260         struct ptlrpc_cli_ctx *ctx;
2261
2262         LASSERT(req->rq_bulk_read || req->rq_bulk_write);
2263
2264         if (!req->rq_pack_bulk)
2265                 return 0;
2266
2267         ctx = req->rq_cli_ctx;
2268         if (ctx->cc_ops->wrap_bulk)
2269                 return ctx->cc_ops->wrap_bulk(ctx, req, desc);
2270         return 0;
2271 }
2272 EXPORT_SYMBOL(sptlrpc_cli_wrap_bulk);
2273
2274 /**
2275  * This is called after unwrap the reply message.
2276  * return nob of actual plain text size received, or error code.
2277  */
2278 int sptlrpc_cli_unwrap_bulk_read(struct ptlrpc_request *req,
2279                                  struct ptlrpc_bulk_desc *desc,
2280                                  int nob)
2281 {
2282         struct ptlrpc_cli_ctx  *ctx;
2283         int                     rc;
2284
2285         LASSERT(req->rq_bulk_read && !req->rq_bulk_write);
2286
2287         if (!req->rq_pack_bulk)
2288                 return desc->bd_nob_transferred;
2289
2290         ctx = req->rq_cli_ctx;
2291         if (ctx->cc_ops->unwrap_bulk) {
2292                 rc = ctx->cc_ops->unwrap_bulk(ctx, req, desc);
2293                 if (rc < 0)
2294                         return rc;
2295         }
2296         return desc->bd_nob_transferred;
2297 }
2298 EXPORT_SYMBOL(sptlrpc_cli_unwrap_bulk_read);
2299
2300 /**
2301  * This is called after unwrap the reply message.
2302  * return 0 for success or error code.
2303  */
2304 int sptlrpc_cli_unwrap_bulk_write(struct ptlrpc_request *req,
2305                                   struct ptlrpc_bulk_desc *desc)
2306 {
2307         struct ptlrpc_cli_ctx  *ctx;
2308         int                     rc;
2309
2310         LASSERT(!req->rq_bulk_read && req->rq_bulk_write);
2311
2312         if (!req->rq_pack_bulk)
2313                 return 0;
2314
2315         ctx = req->rq_cli_ctx;
2316         if (ctx->cc_ops->unwrap_bulk) {
2317                 rc = ctx->cc_ops->unwrap_bulk(ctx, req, desc);
2318                 if (rc < 0)
2319                         return rc;
2320         }
2321
2322         /*
2323          * if everything is going right, nob should equals to nob_transferred.
2324          * in case of privacy mode, nob_transferred needs to be adjusted.
2325          */
2326         if (desc->bd_nob != desc->bd_nob_transferred) {
2327                 CERROR("nob %d doesn't match transferred nob %d\n",
2328                        desc->bd_nob, desc->bd_nob_transferred);
2329                 return -EPROTO;
2330         }
2331
2332         return 0;
2333 }
2334 EXPORT_SYMBOL(sptlrpc_cli_unwrap_bulk_write);
2335
2336 #ifdef HAVE_SERVER_SUPPORT
2337 /**
2338  * Performe transformation upon outgoing bulk read.
2339  */
2340 int sptlrpc_svc_wrap_bulk(struct ptlrpc_request *req,
2341                           struct ptlrpc_bulk_desc *desc)
2342 {
2343         struct ptlrpc_svc_ctx *ctx;
2344
2345         LASSERT(req->rq_bulk_read);
2346
2347         if (!req->rq_pack_bulk)
2348                 return 0;
2349
2350         ctx = req->rq_svc_ctx;
2351         if (ctx->sc_policy->sp_sops->wrap_bulk)
2352                 return ctx->sc_policy->sp_sops->wrap_bulk(req, desc);
2353
2354         return 0;
2355 }
2356 EXPORT_SYMBOL(sptlrpc_svc_wrap_bulk);
2357
2358 /**
2359  * Performe transformation upon incoming bulk write.
2360  */
2361 int sptlrpc_svc_unwrap_bulk(struct ptlrpc_request *req,
2362                             struct ptlrpc_bulk_desc *desc)
2363 {
2364         struct ptlrpc_svc_ctx *ctx;
2365         int                    rc;
2366
2367         LASSERT(req->rq_bulk_write);
2368
2369         /*
2370          * if it's in privacy mode, transferred should >= expected; otherwise
2371          * transferred should == expected.
2372          */
2373         if (desc->bd_nob_transferred < desc->bd_nob ||
2374             (desc->bd_nob_transferred > desc->bd_nob &&
2375              SPTLRPC_FLVR_BULK_SVC(req->rq_flvr.sf_rpc) !=
2376              SPTLRPC_BULK_SVC_PRIV)) {
2377                 DEBUG_REQ(D_ERROR, req, "truncated bulk GET %d(%d)",
2378                           desc->bd_nob_transferred, desc->bd_nob);
2379                 return -ETIMEDOUT;
2380         }
2381
2382         if (!req->rq_pack_bulk)
2383                 return 0;
2384
2385         ctx = req->rq_svc_ctx;
2386         if (ctx->sc_policy->sp_sops->unwrap_bulk) {
2387                 rc = ctx->sc_policy->sp_sops->unwrap_bulk(req, desc);
2388                 if (rc)
2389                         CERROR("error unwrap bulk: %d\n", rc);
2390         }
2391
2392         /* return 0 to allow reply be sent */
2393         return 0;
2394 }
2395 EXPORT_SYMBOL(sptlrpc_svc_unwrap_bulk);
2396
2397 /**
2398  * Prepare buffers for incoming bulk write.
2399  */
2400 int sptlrpc_svc_prep_bulk(struct ptlrpc_request *req,
2401                           struct ptlrpc_bulk_desc *desc)
2402 {
2403         struct ptlrpc_svc_ctx *ctx;
2404
2405         LASSERT(req->rq_bulk_write);
2406
2407         if (!req->rq_pack_bulk)
2408                 return 0;
2409
2410         ctx = req->rq_svc_ctx;
2411         if (ctx->sc_policy->sp_sops->prep_bulk)
2412                 return ctx->sc_policy->sp_sops->prep_bulk(req, desc);
2413
2414         return 0;
2415 }
2416 EXPORT_SYMBOL(sptlrpc_svc_prep_bulk);
2417
2418 #endif /* HAVE_SERVER_SUPPORT */
2419
2420 /****************************************
2421  * user descriptor helpers              *
2422  ****************************************/
2423
2424 int sptlrpc_current_user_desc_size(void)
2425 {
2426         int ngroups;
2427
2428         ngroups = current_ngroups;
2429
2430         if (ngroups > LUSTRE_MAX_GROUPS)
2431                 ngroups = LUSTRE_MAX_GROUPS;
2432         return sptlrpc_user_desc_size(ngroups);
2433 }
2434 EXPORT_SYMBOL(sptlrpc_current_user_desc_size);
2435
2436 int sptlrpc_pack_user_desc(struct lustre_msg *msg, int offset)
2437 {
2438         struct ptlrpc_user_desc *pud;
2439
2440         pud = lustre_msg_buf(msg, offset, 0);
2441
2442         pud->pud_uid = from_kuid(&init_user_ns, current_uid());
2443         pud->pud_gid = from_kgid(&init_user_ns, current_gid());
2444         pud->pud_fsuid = from_kuid(&init_user_ns, current_fsuid());
2445         pud->pud_fsgid = from_kgid(&init_user_ns, current_fsgid());
2446         pud->pud_cap = cfs_curproc_cap_pack();
2447         pud->pud_ngroups = (msg->lm_buflens[offset] - sizeof(*pud)) / 4;
2448
2449         task_lock(current);
2450         if (pud->pud_ngroups > current_ngroups)
2451                 pud->pud_ngroups = current_ngroups;
2452         memcpy(pud->pud_groups, current_cred()->group_info->blocks[0],
2453                pud->pud_ngroups * sizeof(__u32));
2454         task_unlock(current);
2455
2456         return 0;
2457 }
2458 EXPORT_SYMBOL(sptlrpc_pack_user_desc);
2459
2460 int sptlrpc_unpack_user_desc(struct lustre_msg *msg, int offset, int swabbed)
2461 {
2462         struct ptlrpc_user_desc *pud;
2463         int                      i;
2464
2465         pud = lustre_msg_buf(msg, offset, sizeof(*pud));
2466         if (!pud)
2467                 return -EINVAL;
2468
2469         if (swabbed) {
2470                 __swab32s(&pud->pud_uid);
2471                 __swab32s(&pud->pud_gid);
2472                 __swab32s(&pud->pud_fsuid);
2473                 __swab32s(&pud->pud_fsgid);
2474                 __swab32s(&pud->pud_cap);
2475                 __swab32s(&pud->pud_ngroups);
2476         }
2477
2478         if (pud->pud_ngroups > LUSTRE_MAX_GROUPS) {
2479                 CERROR("%u groups is too large\n", pud->pud_ngroups);
2480                 return -EINVAL;
2481         }
2482
2483         if (sizeof(*pud) + pud->pud_ngroups * sizeof(__u32) >
2484             msg->lm_buflens[offset]) {
2485                 CERROR("%u groups are claimed but bufsize only %u\n",
2486                        pud->pud_ngroups, msg->lm_buflens[offset]);
2487                 return -EINVAL;
2488         }
2489
2490         if (swabbed) {
2491                 for (i = 0; i < pud->pud_ngroups; i++)
2492                         __swab32s(&pud->pud_groups[i]);
2493         }
2494
2495         return 0;
2496 }
2497 EXPORT_SYMBOL(sptlrpc_unpack_user_desc);
2498
2499 /****************************************
2500  * misc helpers                         *
2501  ****************************************/
2502
2503 const char * sec2target_str(struct ptlrpc_sec *sec)
2504 {
2505         if (!sec || !sec->ps_import || !sec->ps_import->imp_obd)
2506                 return "*";
2507         if (sec_is_reverse(sec))
2508                 return "c";
2509         return obd_uuid2str(&sec->ps_import->imp_obd->u.cli.cl_target_uuid);
2510 }
2511 EXPORT_SYMBOL(sec2target_str);
2512
2513 /*
2514  * return true if the bulk data is protected
2515  */
2516 int sptlrpc_flavor_has_bulk(struct sptlrpc_flavor *flvr)
2517 {
2518         switch (SPTLRPC_FLVR_BULK_SVC(flvr->sf_rpc)) {
2519         case SPTLRPC_BULK_SVC_INTG:
2520         case SPTLRPC_BULK_SVC_PRIV:
2521                 return 1;
2522         default:
2523                 return 0;
2524         }
2525 }
2526 EXPORT_SYMBOL(sptlrpc_flavor_has_bulk);
2527
2528 /****************************************
2529  * crypto API helper/alloc blkciper     *
2530  ****************************************/
2531
2532 /****************************************
2533  * initialize/finalize                  *
2534  ****************************************/
2535
2536 int sptlrpc_init(void)
2537 {
2538         int rc;
2539
2540         rwlock_init(&policy_lock);
2541
2542         rc = sptlrpc_gc_init();
2543         if (rc)
2544                 goto out;
2545
2546         rc = sptlrpc_conf_init();
2547         if (rc)
2548                 goto out_gc;
2549
2550         rc = sptlrpc_enc_pool_init();
2551         if (rc)
2552                 goto out_conf;
2553
2554         rc = sptlrpc_null_init();
2555         if (rc)
2556                 goto out_pool;
2557
2558         rc = sptlrpc_plain_init();
2559         if (rc)
2560                 goto out_null;
2561
2562         rc = sptlrpc_lproc_init();
2563         if (rc)
2564                 goto out_plain;
2565
2566         return 0;
2567
2568 out_plain:
2569         sptlrpc_plain_fini();
2570 out_null:
2571         sptlrpc_null_fini();
2572 out_pool:
2573         sptlrpc_enc_pool_fini();
2574 out_conf:
2575         sptlrpc_conf_fini();
2576 out_gc:
2577         sptlrpc_gc_fini();
2578 out:
2579         return rc;
2580 }
2581
2582 void sptlrpc_fini(void)
2583 {
2584         sptlrpc_lproc_fini();
2585         sptlrpc_plain_fini();
2586         sptlrpc_null_fini();
2587         sptlrpc_enc_pool_fini();
2588         sptlrpc_conf_fini();
2589         sptlrpc_gc_fini();
2590 }