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