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 //#include <linux/lustre_idl.h>
27 enum ptlrpcs_major_flavors {
28 PTLRPCS_FLVR_MAJOR_NULL = 0,
29 PTLRPCS_FLVR_MAJOR_GSS = 1,
30 PTLRPCS_FLVR_MAJOR_MAX,
33 enum ptlrpcs_null_minor_flavors {
34 PTLRPCS_FLVR_MINOR_NULL = 0,
35 PTLRPCS_FLVR_MINOR_NULL_MAX,
37 enum ptlrpcs_gss_minor_flavors {
38 PTLRPCS_FLVR_MINOR_GSS_NONE = 0,
39 PTLRPCS_FLVR_MINOR_GSS_KRB5 = 1,
40 PTLRPCS_FLVR_MINOR_GSS_MAX,
43 enum ptlrpcs_security_type {
44 PTLRPCS_SVC_NONE = 0, /* no security */
45 PTLRPCS_SVC_AUTH = 1, /* authentication */
46 PTLRPCS_SVC_PRIV = 2, /* privacy */
51 * flavor compose/extract
53 #define SEC_FLAVOR_MAJOR_OFFSET (24)
54 #define SEC_FLAVOR_RESERVE_OFFSET (16)
55 #define SEC_FLAVOR_SVC_OFFSET (8)
56 #define SEC_FLAVOR_MINOR_OFFSET (0)
58 #define SEC_MAKE_FLAVOR(major, minor, svc) \
59 (((__u32)(major) << SEC_FLAVOR_MAJOR_OFFSET) | \
60 ((__u32)(svc) << SEC_FLAVOR_SVC_OFFSET) | \
61 ((__u32)(minor) << SEC_FLAVOR_MINOR_OFFSET))
63 #define SEC_MAKE_SUBFLAVOR(minor, svc) \
64 (((__u32)(svc) << SEC_FLAVOR_SVC_OFFSET) | \
65 ((__u32)(minor) << SEC_FLAVOR_MINOR_OFFSET))
67 #define SEC_FLAVOR_MAJOR(flavor) \
68 ((((__u32)(flavor)) >> SEC_FLAVOR_MAJOR_OFFSET) & 0xFF)
69 #define SEC_FLAVOR_MINOR(flavor) \
70 ((((__u32)(flavor)) >> SEC_FLAVOR_MINOR_OFFSET) & 0xFF)
71 #define SEC_FLAVOR_SVC(flavor) \
72 ((((__u32)(flavor)) >> SEC_FLAVOR_SVC_OFFSET) & 0xFF)
73 #define SEC_FLAVOR_SUB(flavor) \
74 ((((__u32)(flavor)) >> SEC_FLAVOR_MINOR_OFFSET) & 0xFFFF)
79 #define PTLRPCS_FLVR_GSS_NONE \
80 SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS, \
81 PTLRPCS_FLVR_MINOR_GSS_NONE, \
83 #define PTLRPCS_FLVR_GSS_AUTH \
84 SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS, \
85 PTLRPCS_FLVR_MINOR_GSS_NONE, \
87 #define PTLRPCS_FLVR_GSS_PRIV \
88 SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS, \
89 PTLRPCS_FLVR_MINOR_GSS_NONE, \
95 #define PTLRPCS_SUBFLVR_KRB5 \
96 SEC_MAKE_SUBFLAVOR(PTLRPCS_FLVR_MINOR_GSS_KRB5, \
98 #define PTLRPCS_SUBFLVR_KRB5I \
99 SEC_MAKE_SUBFLAVOR(PTLRPCS_FLVR_MINOR_GSS_KRB5, \
101 #define PTLRPCS_SUBFLVR_KRB5P \
102 SEC_MAKE_SUBFLAVOR(PTLRPCS_FLVR_MINOR_GSS_KRB5, \
108 #define PTLRPCS_FLVR_NULL \
109 SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_NULL, \
110 PTLRPCS_FLVR_MINOR_NULL, \
112 #define PTLRPCS_FLVR_KRB5 \
113 SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS, \
114 PTLRPCS_FLVR_MINOR_GSS_KRB5, \
116 #define PTLRPCS_FLVR_KRB5I \
117 SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS, \
118 PTLRPCS_FLVR_MINOR_GSS_KRB5, \
120 #define PTLRPCS_FLVR_KRB5P \
121 SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS, \
122 PTLRPCS_FLVR_MINOR_GSS_KRB5, \
125 #define PTLRPCS_FLVR_INVALID (-1)
127 __u32 ptlrpcs_name2flavor(const char *name);
128 char *ptlrpcs_flavor2name(__u32 flavor);
133 /* forward declaration */
135 struct ptlrpc_request;
137 struct ptlrpc_credops;
139 struct ptlrpc_secops;
143 struct list_head list;
148 * This header is prepended at any on-wire ptlrpc packets
150 struct ptlrpcs_wire_hdr {
158 struct ptlrpcs_wire_hdr *buf_to_sec_hdr(void *buf)
160 return (struct ptlrpcs_wire_hdr *) buf;
164 struct lustre_msg *buf_to_lustre_msg(void *buf)
166 return (struct lustre_msg *)
167 ((char *) buf + sizeof(struct ptlrpcs_wire_hdr));
171 __u8 *buf_to_sec_data(void *buf)
173 struct ptlrpcs_wire_hdr *hdr = buf_to_sec_hdr(buf);
174 return (__u8 *) (buf + sizeof(*hdr) + hdr->msg_len);
177 #define PTLRPC_SEC_GSS_VERSION (1)
179 enum ptlrpcs_gss_proc {
180 PTLRPCS_GSS_PROC_DATA = 0,
181 PTLRPCS_GSS_PROC_INIT = 1,
182 PTLRPCS_GSS_PROC_CONTINUE_INIT = 2,
183 PTLRPCS_GSS_PROC_DESTROY = 3,
184 PTLRPCS_GSS_PROC_ERR = 4,
187 enum ptlrpcs_gss_svc {
188 PTLRPCS_GSS_SVC_NONE = 1,
189 PTLRPCS_GSS_SVC_INTEGRITY = 2,
190 PTLRPCS_GSS_SVC_PRIVACY = 3,
196 PTLRPCS_REJECTEDCRED = 2,
198 PTLRPCS_REJECTEDVERF = 4,
201 PTLRPCS_GSS_CREDPROBLEM = 13,
202 PTLRPCS_GSS_CTXPROBLEM = 14,
209 struct group_info *vc_ginfo;
212 struct ptlrpc_credops {
213 int (*match) (struct ptlrpc_cred *cred, struct vfs_cred *vcred);
214 int (*refresh)(struct ptlrpc_cred *cred);
215 void (*destroy)(struct ptlrpc_cred *cred);
216 int (*sign) (struct ptlrpc_cred *cred,
217 struct ptlrpc_request *req);
218 int (*verify) (struct ptlrpc_cred *cred,
219 struct ptlrpc_request *req);
220 int (*seal) (struct ptlrpc_cred *cred,
221 struct ptlrpc_request *req);
222 int (*unseal) (struct ptlrpc_cred *cred,
223 struct ptlrpc_request *req);
226 #define PTLRPC_CRED_UPTODATE_BIT 0 /* uptodate */
227 #define PTLRPC_CRED_DEAD_BIT 1 /* mark expired gracefully */
228 #define PTLRPC_CRED_ERROR_BIT 2 /* fatal error (refresh, etc.) */
230 #define PTLRPC_CRED_UPTODATE (1 << PTLRPC_CRED_UPTODATE_BIT)
231 #define PTLRPC_CRED_DEAD (1 << PTLRPC_CRED_DEAD_BIT)
232 #define PTLRPC_CRED_ERROR (1 << PTLRPC_CRED_ERROR_BIT)
234 #define PTLRPC_CRED_FLAGS_MASK (PTLRPC_CRED_UPTODATE | \
239 struct list_head pc_hash; /* linked into hash table */
240 atomic_t pc_refcount;
241 struct ptlrpc_sec *pc_sec;
242 struct ptlrpc_credops *pc_ops;
243 unsigned long pc_expire;
244 unsigned long pc_flags;
245 /* XXX maybe should not be here */
250 struct ptlrpc_secops {
251 struct ptlrpc_sec * (*create_sec) (__u32 flavor,
252 const char *pipe_dir,
254 void (*destroy_sec) (struct ptlrpc_sec *sec);
255 struct ptlrpc_cred * (*create_cred) (struct ptlrpc_sec *sec,
256 struct vfs_cred *vcred);
257 /* buffer manipulation */
258 int (*alloc_reqbuf) (struct ptlrpc_sec *sec,
259 struct ptlrpc_request *req,
260 int lustre_msg_size);
261 int (*alloc_repbuf) (struct ptlrpc_sec *sec,
262 struct ptlrpc_request *req,
263 int lustre_msg_size);
264 void (*free_reqbuf) (struct ptlrpc_sec *sec,
265 struct ptlrpc_request *req);
266 void (*free_repbuf) (struct ptlrpc_sec *sec,
267 struct ptlrpc_request *req);
268 /* security payload size estimation */
269 int (*est_req_payload)(struct ptlrpc_sec *sec,
270 struct ptlrpc_request *req,
272 int (*est_rep_payload)(struct ptlrpc_sec *sec,
273 struct ptlrpc_request *req,
277 struct ptlrpc_sec_type {
278 struct module *pst_owner;
280 atomic_t pst_inst; /* instance, debug only */
281 __u32 pst_flavor; /* major flavor */
282 struct ptlrpc_secops *pst_ops;
285 #define PTLRPC_SEC_FL_MDS 0x0001 /* outgoing from MDS */
286 #define PTLRPC_SEC_FL_REVERSE 0x0002 /* reverse sec */
287 #define PTLRPC_SEC_FL_PAG 0x0004 /* enable PAG */
289 #define PTLRPC_CREDCACHE_NR 8
290 #define PTLRPC_CREDCACHE_MASK (PTLRPC_CREDCACHE_NR - 1)
293 struct ptlrpc_sec_type *ps_type;
294 struct list_head ps_credcache[PTLRPC_CREDCACHE_NR];
295 spinlock_t ps_lock; /* protect cred cache */
297 atomic_t ps_refcount;
298 atomic_t ps_credcount;
299 struct obd_import *ps_import;
300 /* actual security model need initialize following fields */
301 unsigned long ps_expire; /* cache expire interval */
302 unsigned long ps_nextgc; /* next gc time */
303 unsigned long ps_flags;
307 int ptlrpcs_register(struct ptlrpc_sec_type *type);
308 int ptlrpcs_unregister(struct ptlrpc_sec_type *type);
310 struct ptlrpc_sec * ptlrpcs_sec_create(__u32 flavor,
312 struct obd_import *import,
313 const char *pipe_dir,
315 void ptlrpcs_sec_put(struct ptlrpc_sec *sec);
316 void ptlrpcs_sec_invalidate_cache(struct ptlrpc_sec *sec);
318 struct ptlrpc_cred * ptlrpcs_cred_lookup(struct ptlrpc_sec *sec,
319 struct vfs_cred *vcred);
320 void ptlrpcs_cred_put(struct ptlrpc_cred *cred, int sync);
322 static inline void ptlrpcs_cred_get(struct ptlrpc_cred *cred)
324 LASSERT(atomic_read(&cred->pc_refcount));
325 atomic_inc(&cred->pc_refcount);
328 static inline int ptlrpcs_cred_refresh(struct ptlrpc_cred *cred)
331 LASSERT(atomic_read(&cred->pc_refcount));
332 LASSERT(cred->pc_ops);
333 LASSERT(cred->pc_ops->refresh);
334 return cred->pc_ops->refresh(cred);
337 static inline int ptlrpcs_cred_is_uptodate(struct ptlrpc_cred *cred)
340 return ((cred->pc_flags & PTLRPC_CRED_FLAGS_MASK) ==
341 PTLRPC_CRED_UPTODATE);
344 static inline int ptlrpcs_cred_is_dead(struct ptlrpc_cred *cred)
347 return ((cred->pc_flags & (PTLRPC_CRED_DEAD | PTLRPC_CRED_ERROR)) != 0);
350 #define ptlrpcs_cred_expire(cred) \
351 if (!test_and_set_bit(PTLRPC_CRED_DEAD_BIT, &cred->pc_flags)) { \
352 CWARN("cred %p: get expired\n", cred); \
353 clear_bit(PTLRPC_CRED_UPTODATE_BIT, &cred->pc_flags); \
356 static inline int ptlrpcs_cred_check_uptodate(struct ptlrpc_cred *cred)
358 LASSERT(atomic_read(&cred->pc_refcount));
360 if (!ptlrpcs_cred_is_uptodate(cred))
363 if (cred->pc_expire == 0)
365 if (time_after(cred->pc_expire, get_seconds()))
367 ptlrpcs_cred_expire(cred);
371 static inline int ptlrpcs_est_req_payload(struct ptlrpc_request *req,
374 struct ptlrpc_sec *sec = req->rq_cred->pc_sec;
375 struct ptlrpc_secops *ops;
378 LASSERT(sec->ps_type);
379 LASSERT(sec->ps_type->pst_ops);
381 ops = sec->ps_type->pst_ops;
382 if (ops->est_req_payload)
383 return ops->est_req_payload(sec, req, datasize);
388 static inline int ptlrpcs_est_rep_payload(struct ptlrpc_request *req,
391 struct ptlrpc_sec *sec = req->rq_cred->pc_sec;
392 struct ptlrpc_secops *ops;
395 LASSERT(sec->ps_type);
396 LASSERT(sec->ps_type->pst_ops);
398 ops = sec->ps_type->pst_ops;
399 if (ops->est_rep_payload)
400 return ops->est_rep_payload(sec, req, datasize);
405 static inline int add_deny_security(char *sec, struct list_head *head)
407 deny_sec_t *p_deny_sec = NULL;
410 LASSERT(sec != NULL);
412 OBD_ALLOC(p_deny_sec, sizeof(*p_deny_sec));
413 if (p_deny_sec == NULL)
416 p_deny_sec->flavor = ptlrpcs_name2flavor(sec);
417 if (p_deny_sec->flavor == PTLRPCS_FLVR_INVALID) {
418 CERROR("unrecognized security type %s\n", (char*) sec);
423 list_add_tail(&p_deny_sec->list, head);
427 OBD_FREE(p_deny_sec, sizeof(*p_deny_sec));
432 int ptlrpcs_cli_wrap_request(struct ptlrpc_request *req);
433 int ptlrpcs_cli_unwrap_reply(struct ptlrpc_request *req);
434 int ptlrpcs_cli_alloc_reqbuf(struct ptlrpc_request *req, int msgsize);
435 int ptlrpcs_cli_alloc_repbuf(struct ptlrpc_request *req, int msgsize);
436 void ptlrpcs_cli_free_reqbuf(struct ptlrpc_request *req);
437 void ptlrpcs_cli_free_repbuf(struct ptlrpc_request *req);
439 /* higher interface */
440 int ptlrpcs_import_get_sec(struct obd_import *imp);
441 void ptlrpcs_import_drop_sec(struct obd_import *imp);
442 void ptlrpcs_import_flush_current_creds(struct obd_import *imp);
443 int ptlrpcs_req_get_cred(struct ptlrpc_request *req);
444 void ptlrpcs_req_drop_cred(struct ptlrpc_request *req);
445 int ptlrpcs_req_replace_dead_cred(struct ptlrpc_request *req);
446 int ptlrpcs_req_refresh_cred(struct ptlrpc_request *req);
447 int ptlrpcs_check_cred(struct obd_import *imp);
449 /* internal helpers */
450 int sec_alloc_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req,
451 int msgsize, int secsize);
452 void sec_free_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req);
455 int ptlrpcs_null_init(void);
456 int ptlrpcs_null_exit(void);
458 /**********************************************************
460 **********************************************************/
462 struct ptlrpc_reply_state;
464 struct ptlrpc_svcsec {
465 struct module *pss_owner;
467 __u32 pss_flavor; /* major flavor */
470 int (*accept) (struct ptlrpc_request *req,
471 enum ptlrpcs_error *res);
472 int (*authorize) (struct ptlrpc_request *req);
473 int (*alloc_repbuf)(struct ptlrpc_svcsec *svcsec,
474 struct ptlrpc_request *req,
476 void (*free_repbuf) (struct ptlrpc_svcsec *svcsec,
477 struct ptlrpc_reply_state *rs);
478 void (*cleanup_req) (struct ptlrpc_svcsec *svcsec,
479 struct ptlrpc_request *req);
483 #define SVC_COMPLETE 2
488 int svcsec_register(struct ptlrpc_svcsec *ss);
489 int svcsec_unregister(struct ptlrpc_svcsec *ss);
490 int svcsec_accept(struct ptlrpc_request *req, enum ptlrpcs_error *res);
491 int svcsec_authorize(struct ptlrpc_request *req);
492 int svcsec_alloc_repbuf(struct ptlrpc_svcsec *svcsec,
493 struct ptlrpc_request *req, int msgsize);
494 void svcsec_cleanup_req(struct ptlrpc_request *req);
496 struct ptlrpc_svcsec * svcsec_get(struct ptlrpc_svcsec *sec);
497 void svcsec_put(struct ptlrpc_svcsec *sec);
499 /* internal helpers */
500 int svcsec_alloc_reply_state(struct ptlrpc_request *req,
501 int msgsize, int secsize);
502 void svcsec_free_reply_state(struct ptlrpc_reply_state *rs);
505 int svcsec_null_init(void);
506 int svcsec_null_exit(void);
509 #include <linux/crypto.h>
511 #define NR_CAPAHASH 32
512 #define CAPA_TIMEOUT 1800 /* sec, == 30 min */
513 #define CAPA_KEY_TIMEOUT (24 * 60 * 60) /* sec, == 1 day */
514 #define CAPA_CACHE_SIZE 1000 /* for MDS & OST */
515 #define CAPA_HMAC_ALG "sha1"
517 struct lustre_capa_data {
518 __u32 lc_uid; /* uid */
519 __u32 lc_op; /* operations allowed */
520 __u64 lc_ino; /* inode# */
521 __u32 lc_mdsid; /* mds# */
522 __u32 lc_keyid; /* key used for the capability */
523 __u64 lc_expiry; /* expiry time: servers have clocks */
524 __u32 lc_flags; /* security features for capability */
525 } __attribute__((packed));
528 struct inode *inode; /* this should be always valid
530 struct lustre_handle handle; /* handle of mds_file_data */
531 struct list_head *list; /* the capa list belong to this client */
532 struct timer_list *timer; /* timer belong to this client */
536 int bvalid; /* black key here valid or not */
537 __u32 bkeyid; /* black key id */
538 __u8 bhmac[CAPA_DIGEST_SIZE]; /* black key */
542 struct hlist_node c_hash;
543 struct list_head c_list;
545 struct lustre_capa c_capa; /* capa */
550 struct client_capa client;
551 struct filter_capa filter;
555 #define c_inode u.client.inode
556 #define c_handle u.client.handle
557 #define c_bvalid u.filter.bvalid
558 #define c_bkeyid u.filter.bkeyid
559 #define c_bhmac u.filter.bhmac
561 enum lustre_capa_type {
567 extern spinlock_t capa_lock;
568 extern struct hlist_head *capa_hash;
569 extern struct list_head capa_list[];
570 extern struct timer_list ll_capa_timer;
572 /* obdclass/capa.c */
573 int capa_op(int flags);
574 void __capa_get(struct obd_capa *ocapa);
575 struct obd_capa *capa_get(uid_t uid, int capa_op, __u64 mdsid,
576 unsigned long ino, int type,
577 struct lustre_capa *capa, struct inode *inode,
578 struct lustre_handle *handle);
579 void capa_put(struct obd_capa *ocapa, int type);
580 int capa_renew(struct lustre_capa *capa, int type);
581 void capa_hmac(struct crypto_tfm *tfm, u8 *key, struct lustre_capa *capa);
582 void capa_dup(void *dst, struct obd_capa *ocapa);
583 void capa_dup2(void *dst, struct lustre_capa *capa);
584 int capa_expired(struct lustre_capa *capa);
585 int __capa_is_to_expire(struct obd_capa *ocapa);
586 int capa_is_to_expire(struct obd_capa *ocapa);
588 #define CAPA_EXPIRY_SHIFT 10 /* 1024 sec */
589 #define CAPA_EXPIRY (1UL << PAGE_SHIFT)
590 #define CAPA_EXPIRY_MASK (~(CAPA_EXPIRY-1))
592 #define CAPA_PRE_EXPIRY_NOROUND 3 /* sec */
593 #define CAPA_PRE_EXPIRY 300 /* sec */
595 /* struct lustre_capa.lc_flags */
596 #define CAPA_FL_NOROUND 0x001 /* capa expiry not rounded */
598 static inline unsigned long capa_pre_expiry(struct lustre_capa *capa)
600 return (capa->lc_flags & CAPA_FL_NOROUND) ?
601 CAPA_PRE_EXPIRY_NOROUND : CAPA_PRE_EXPIRY;
605 round_expiry(__u32 timeout)
610 do_gettimeofday(&tv);
611 expiry = tv.tv_sec + timeout;
613 if (timeout > CAPA_EXPIRY)
614 expiry = (expiry + CAPA_EXPIRY - 1) & CAPA_EXPIRY_MASK;
620 capa_key_cmp(struct lustre_capa_key *k1, struct lustre_capa_key *k2)
622 return le32_to_cpu(k1->lk_keyid) - le32_to_cpu(k2->lk_keyid);
625 static inline unsigned long
626 expiry_to_jiffies(__u64 expiry)
631 do_gettimeofday(&tv);
632 return jiffies + ((unsigned long)expiry - tv.tv_sec) * HZ;
635 #endif /* __KERNEL__ */
637 struct mds_capa_key {
638 struct list_head k_list;
640 struct lustre_capa_key *k_key;
641 struct obd_device *k_obd;
644 struct filter_capa_key {
645 struct list_head k_list;
647 struct lustre_capa_key k_key;
650 #endif /* __LINUX_SEC_H_ */