1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 * Copyright (C) 2004 Cluster File Systems, Inc.
6 * This file is part of Lustre, http://www.lustre.org.
8 * Lustre is free software; you can redistribute it and/or
9 * modify it under the terms of version 2 of the GNU General Public
10 * License as published by the Free Software Foundation.
12 * Lustre is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Lustre; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #ifndef __LINUX_SEC_H_
23 #define __LINUX_SEC_H_
25 enum ptlrpcs_major_flavors {
26 PTLRPCS_FLVR_MAJOR_NULL = 0,
27 PTLRPCS_FLVR_MAJOR_GSS = 1,
28 PTLRPCS_FLVR_MAJOR_MAX,
31 enum ptlrpcs_null_minor_flavors {
32 PTLRPCS_FLVR_MINOR_NULL = 0,
33 PTLRPCS_FLVR_MINOR_NULL_MAX,
35 enum ptlrpcs_gss_minor_flavors {
36 PTLRPCS_FLVR_MINOR_GSS_NONE = 0,
37 PTLRPCS_FLVR_MINOR_GSS_KRB5 = 1,
38 PTLRPCS_FLVR_MINOR_GSS_MAX,
41 enum ptlrpcs_security_type {
42 PTLRPCS_SVC_NONE = 0, /* no security */
43 PTLRPCS_SVC_AUTH = 1, /* authentication */
44 PTLRPCS_SVC_PRIV = 2, /* privacy */
49 * flavor compose/extract
51 #define SEC_FLAVOR_MAJOR_OFFSET (24)
52 #define SEC_FLAVOR_RESERVE_OFFSET (16)
53 #define SEC_FLAVOR_SVC_OFFSET (8)
54 #define SEC_FLAVOR_MINOR_OFFSET (0)
56 #define SEC_MAKE_FLAVOR(major, minor, svc) \
57 (((__u32)(major) << SEC_FLAVOR_MAJOR_OFFSET) | \
58 ((__u32)(svc) << SEC_FLAVOR_SVC_OFFSET) | \
59 ((__u32)(minor) << SEC_FLAVOR_MINOR_OFFSET))
61 #define SEC_MAKE_SUBFLAVOR(minor, svc) \
62 (((__u32)(svc) << SEC_FLAVOR_SVC_OFFSET) | \
63 ((__u32)(minor) << SEC_FLAVOR_MINOR_OFFSET))
65 #define SEC_FLAVOR_MAJOR(flavor) \
66 ((((__u32)(flavor)) >> SEC_FLAVOR_MAJOR_OFFSET) & 0xFF)
67 #define SEC_FLAVOR_MINOR(flavor) \
68 ((((__u32)(flavor)) >> SEC_FLAVOR_MINOR_OFFSET) & 0xFF)
69 #define SEC_FLAVOR_SVC(flavor) \
70 ((((__u32)(flavor)) >> SEC_FLAVOR_SVC_OFFSET) & 0xFF)
71 #define SEC_FLAVOR_SUB(flavor) \
72 ((((__u32)(flavor)) >> SEC_FLAVOR_MINOR_OFFSET) & 0xFFFF)
77 #define PTLRPCS_FLVR_GSS_NONE \
78 SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS, \
79 PTLRPCS_FLVR_MINOR_GSS_NONE, \
81 #define PTLRPCS_FLVR_GSS_AUTH \
82 SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS, \
83 PTLRPCS_FLVR_MINOR_GSS_NONE, \
85 #define PTLRPCS_FLVR_GSS_PRIV \
86 SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS, \
87 PTLRPCS_FLVR_MINOR_GSS_NONE, \
93 #define PTLRPCS_SUBFLVR_KRB5 \
94 SEC_MAKE_SUBFLAVOR(PTLRPCS_FLVR_MINOR_GSS_KRB5, \
96 #define PTLRPCS_SUBFLVR_KRB5I \
97 SEC_MAKE_SUBFLAVOR(PTLRPCS_FLVR_MINOR_GSS_KRB5, \
99 #define PTLRPCS_SUBFLVR_KRB5P \
100 SEC_MAKE_SUBFLAVOR(PTLRPCS_FLVR_MINOR_GSS_KRB5, \
106 #define PTLRPCS_FLVR_NULL \
107 SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_NULL, \
108 PTLRPCS_FLVR_MINOR_NULL, \
110 #define PTLRPCS_FLVR_KRB5 \
111 SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS, \
112 PTLRPCS_FLVR_MINOR_GSS_KRB5, \
114 #define PTLRPCS_FLVR_KRB5I \
115 SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS, \
116 PTLRPCS_FLVR_MINOR_GSS_KRB5, \
118 #define PTLRPCS_FLVR_KRB5P \
119 SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS, \
120 PTLRPCS_FLVR_MINOR_GSS_KRB5, \
123 #define PTLRPCS_FLVR_INVALID (-1)
125 __u32 ptlrpcs_name2flavor(const char *name);
126 char *ptlrpcs_flavor2name(__u32 flavor);
131 /* forward declaration */
133 struct ptlrpc_request;
135 struct ptlrpc_credops;
137 struct ptlrpc_secops;
141 struct list_head list;
146 * This header is prepended at any on-wire ptlrpc packets
148 struct ptlrpcs_wire_hdr {
156 struct ptlrpcs_wire_hdr *buf_to_sec_hdr(void *buf)
158 return (struct ptlrpcs_wire_hdr *) buf;
162 struct lustre_msg *buf_to_lustre_msg(void *buf)
164 return (struct lustre_msg *)
165 ((char *) buf + sizeof(struct ptlrpcs_wire_hdr));
169 __u8 *buf_to_sec_data(void *buf)
171 struct ptlrpcs_wire_hdr *hdr = buf_to_sec_hdr(buf);
172 return (__u8 *) (buf + sizeof(*hdr) + hdr->msg_len);
175 #define PTLRPC_SEC_GSS_VERSION (1)
177 enum ptlrpcs_gss_proc {
178 PTLRPCS_GSS_PROC_DATA = 0,
179 PTLRPCS_GSS_PROC_INIT = 1,
180 PTLRPCS_GSS_PROC_CONTINUE_INIT = 2,
181 PTLRPCS_GSS_PROC_DESTROY = 3,
182 PTLRPCS_GSS_PROC_ERR = 4,
185 enum ptlrpcs_gss_svc {
186 PTLRPCS_GSS_SVC_NONE = 1,
187 PTLRPCS_GSS_SVC_INTEGRITY = 2,
188 PTLRPCS_GSS_SVC_PRIVACY = 3,
194 PTLRPCS_REJECTEDCRED = 2,
196 PTLRPCS_REJECTEDVERF = 4,
199 PTLRPCS_GSS_CREDPROBLEM = 13,
200 PTLRPCS_GSS_CTXPROBLEM = 14,
207 struct group_info *vc_ginfo;
210 struct ptlrpc_credops {
211 int (*match) (struct ptlrpc_cred *cred, struct vfs_cred *vcred);
212 int (*refresh)(struct ptlrpc_cred *cred);
213 void (*destroy)(struct ptlrpc_cred *cred);
214 int (*sign) (struct ptlrpc_cred *cred,
215 struct ptlrpc_request *req);
216 int (*verify) (struct ptlrpc_cred *cred,
217 struct ptlrpc_request *req);
218 int (*seal) (struct ptlrpc_cred *cred,
219 struct ptlrpc_request *req);
220 int (*unseal) (struct ptlrpc_cred *cred,
221 struct ptlrpc_request *req);
224 #define PTLRPC_CRED_UPTODATE_BIT 0 /* uptodate */
225 #define PTLRPC_CRED_DEAD_BIT 1 /* mark expired gracefully */
226 #define PTLRPC_CRED_ERROR_BIT 2 /* fatal error (refresh, etc.) */
228 #define PTLRPC_CRED_UPTODATE (1 << PTLRPC_CRED_UPTODATE_BIT)
229 #define PTLRPC_CRED_DEAD (1 << PTLRPC_CRED_DEAD_BIT)
230 #define PTLRPC_CRED_ERROR (1 << PTLRPC_CRED_ERROR_BIT)
232 #define PTLRPC_CRED_FLAGS_MASK (PTLRPC_CRED_UPTODATE | \
237 struct list_head pc_hash; /* linked into hash table */
238 atomic_t pc_refcount;
239 struct ptlrpc_sec *pc_sec;
240 struct ptlrpc_credops *pc_ops;
241 unsigned long pc_expire;
242 unsigned long pc_flags;
243 /* XXX maybe should not be here */
248 struct ptlrpc_secops {
249 struct ptlrpc_sec * (*create_sec) (__u32 flavor,
250 const char *pipe_dir,
252 void (*destroy_sec) (struct ptlrpc_sec *sec);
253 struct ptlrpc_cred * (*create_cred) (struct ptlrpc_sec *sec,
254 struct vfs_cred *vcred);
255 /* buffer manipulation */
256 int (*alloc_reqbuf) (struct ptlrpc_sec *sec,
257 struct ptlrpc_request *req,
258 int lustre_msg_size);
259 int (*alloc_repbuf) (struct ptlrpc_sec *sec,
260 struct ptlrpc_request *req,
261 int lustre_msg_size);
262 void (*free_reqbuf) (struct ptlrpc_sec *sec,
263 struct ptlrpc_request *req);
264 void (*free_repbuf) (struct ptlrpc_sec *sec,
265 struct ptlrpc_request *req);
266 /* security payload size estimation */
267 int (*est_req_payload)(struct ptlrpc_sec *sec,
268 struct ptlrpc_request *req,
270 int (*est_rep_payload)(struct ptlrpc_sec *sec,
271 struct ptlrpc_request *req,
275 struct ptlrpc_sec_type {
276 struct module *pst_owner;
278 atomic_t pst_inst; /* instance, debug only */
279 __u32 pst_flavor; /* major flavor */
280 struct ptlrpc_secops *pst_ops;
283 #define PTLRPC_SEC_FL_MDS 0x0001 /* outgoing from MDS */
284 #define PTLRPC_SEC_FL_REVERSE 0x0002 /* reverse sec */
285 #define PTLRPC_SEC_FL_PAG 0x0004 /* enable PAG */
287 #define PTLRPC_CREDCACHE_NR 8
288 #define PTLRPC_CREDCACHE_MASK (PTLRPC_CREDCACHE_NR - 1)
291 struct ptlrpc_sec_type *ps_type;
292 struct list_head ps_credcache[PTLRPC_CREDCACHE_NR];
293 spinlock_t ps_lock; /* protect cred cache */
295 atomic_t ps_refcount;
296 atomic_t ps_credcount;
297 struct obd_import *ps_import;
298 /* actual security model need initialize following fields */
299 unsigned long ps_expire; /* cache expire interval */
300 unsigned long ps_nextgc; /* next gc time */
301 unsigned long ps_flags;
305 int ptlrpcs_register(struct ptlrpc_sec_type *type);
306 int ptlrpcs_unregister(struct ptlrpc_sec_type *type);
308 struct ptlrpc_sec * ptlrpcs_sec_create(__u32 flavor,
310 struct obd_import *import,
311 const char *pipe_dir,
313 void ptlrpcs_sec_put(struct ptlrpc_sec *sec);
314 void ptlrpcs_sec_invalidate_cache(struct ptlrpc_sec *sec);
316 struct ptlrpc_cred * ptlrpcs_cred_lookup(struct ptlrpc_sec *sec,
317 struct vfs_cred *vcred);
318 void ptlrpcs_cred_put(struct ptlrpc_cred *cred, int sync);
320 static inline void ptlrpcs_cred_get(struct ptlrpc_cred *cred)
322 LASSERT(atomic_read(&cred->pc_refcount));
323 atomic_inc(&cred->pc_refcount);
326 static inline int ptlrpcs_cred_refresh(struct ptlrpc_cred *cred)
329 LASSERT(atomic_read(&cred->pc_refcount));
330 LASSERT(cred->pc_ops);
331 LASSERT(cred->pc_ops->refresh);
332 return cred->pc_ops->refresh(cred);
335 static inline int ptlrpcs_cred_is_uptodate(struct ptlrpc_cred *cred)
338 return ((cred->pc_flags & PTLRPC_CRED_FLAGS_MASK) ==
339 PTLRPC_CRED_UPTODATE);
342 static inline int ptlrpcs_cred_is_dead(struct ptlrpc_cred *cred)
345 return ((cred->pc_flags & (PTLRPC_CRED_DEAD | PTLRPC_CRED_ERROR)) != 0);
348 #define ptlrpcs_cred_expire(cred) \
349 if (!test_and_set_bit(PTLRPC_CRED_DEAD_BIT, &cred->pc_flags)) { \
350 CWARN("cred %p: get expired\n", cred); \
351 clear_bit(PTLRPC_CRED_UPTODATE_BIT, &cred->pc_flags); \
354 static inline int ptlrpcs_cred_check_uptodate(struct ptlrpc_cred *cred)
356 LASSERT(atomic_read(&cred->pc_refcount));
358 if (!ptlrpcs_cred_is_uptodate(cred))
361 if (cred->pc_expire == 0)
363 if (time_after(cred->pc_expire, get_seconds()))
365 ptlrpcs_cred_expire(cred);
369 static inline int ptlrpcs_est_req_payload(struct ptlrpc_request *req,
372 struct ptlrpc_sec *sec = req->rq_cred->pc_sec;
373 struct ptlrpc_secops *ops;
376 LASSERT(sec->ps_type);
377 LASSERT(sec->ps_type->pst_ops);
379 ops = sec->ps_type->pst_ops;
380 if (ops->est_req_payload)
381 return ops->est_req_payload(sec, req, datasize);
386 static inline int ptlrpcs_est_rep_payload(struct ptlrpc_request *req,
389 struct ptlrpc_sec *sec = req->rq_cred->pc_sec;
390 struct ptlrpc_secops *ops;
393 LASSERT(sec->ps_type);
394 LASSERT(sec->ps_type->pst_ops);
396 ops = sec->ps_type->pst_ops;
397 if (ops->est_rep_payload)
398 return ops->est_rep_payload(sec, req, datasize);
403 static inline int add_deny_security(char *sec, struct list_head *head)
405 deny_sec_t *p_deny_sec = NULL;
408 LASSERT(sec != NULL);
410 OBD_ALLOC(p_deny_sec, sizeof(*p_deny_sec));
411 if (p_deny_sec == NULL)
414 p_deny_sec->flavor = ptlrpcs_name2flavor(sec);
415 if (p_deny_sec->flavor == PTLRPCS_FLVR_INVALID) {
416 CERROR("unrecognized security type %s\n", (char*) sec);
421 list_add_tail(&p_deny_sec->list, head);
425 OBD_FREE(p_deny_sec, sizeof(*p_deny_sec));
430 int ptlrpcs_cli_wrap_request(struct ptlrpc_request *req);
431 int ptlrpcs_cli_unwrap_reply(struct ptlrpc_request *req);
432 int ptlrpcs_cli_alloc_reqbuf(struct ptlrpc_request *req, int msgsize);
433 int ptlrpcs_cli_alloc_repbuf(struct ptlrpc_request *req, int msgsize);
434 void ptlrpcs_cli_free_reqbuf(struct ptlrpc_request *req);
435 void ptlrpcs_cli_free_repbuf(struct ptlrpc_request *req);
437 /* higher interface */
438 int ptlrpcs_import_get_sec(struct obd_import *imp);
439 void ptlrpcs_import_drop_sec(struct obd_import *imp);
440 void ptlrpcs_import_flush_current_creds(struct obd_import *imp);
441 int ptlrpcs_req_get_cred(struct ptlrpc_request *req);
442 void ptlrpcs_req_drop_cred(struct ptlrpc_request *req);
443 int ptlrpcs_req_replace_dead_cred(struct ptlrpc_request *req);
444 int ptlrpcs_req_refresh_cred(struct ptlrpc_request *req);
445 int ptlrpcs_check_cred(struct obd_import *imp);
447 /* internal helpers */
448 int sec_alloc_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req,
449 int msgsize, int secsize);
450 void sec_free_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req);
453 int ptlrpcs_null_init(void);
454 int ptlrpcs_null_exit(void);
456 /**********************************************************
458 **********************************************************/
460 struct ptlrpc_reply_state;
462 struct ptlrpc_svcsec {
463 struct module *pss_owner;
465 __u32 pss_flavor; /* major flavor */
468 int (*accept) (struct ptlrpc_request *req,
469 enum ptlrpcs_error *res);
470 int (*authorize) (struct ptlrpc_request *req);
471 int (*alloc_repbuf)(struct ptlrpc_svcsec *svcsec,
472 struct ptlrpc_request *req,
474 void (*free_repbuf) (struct ptlrpc_svcsec *svcsec,
475 struct ptlrpc_reply_state *rs);
476 void (*cleanup_req) (struct ptlrpc_svcsec *svcsec,
477 struct ptlrpc_request *req);
481 #define SVC_COMPLETE 2
486 int svcsec_register(struct ptlrpc_svcsec *ss);
487 int svcsec_unregister(struct ptlrpc_svcsec *ss);
488 int svcsec_accept(struct ptlrpc_request *req, enum ptlrpcs_error *res);
489 int svcsec_authorize(struct ptlrpc_request *req);
490 int svcsec_alloc_repbuf(struct ptlrpc_svcsec *svcsec,
491 struct ptlrpc_request *req, int msgsize);
492 void svcsec_cleanup_req(struct ptlrpc_request *req);
494 struct ptlrpc_svcsec * svcsec_get(struct ptlrpc_svcsec *sec);
495 void svcsec_put(struct ptlrpc_svcsec *sec);
497 /* internal helpers */
498 int svcsec_alloc_reply_state(struct ptlrpc_request *req,
499 int msgsize, int secsize);
500 void svcsec_free_reply_state(struct ptlrpc_reply_state *rs);
503 int svcsec_null_init(void);
504 int svcsec_null_exit(void);
506 #endif /* __KERNEL__ */
508 #endif /* __LINUX_SEC_H_ */