Whamcloud - gitweb
Land b_hd_capa onto HEAD (20050809_1942)
[fs/lustre-release.git] / lustre / include / linux / lustre_sec.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Copyright (C) 2004 Cluster File Systems, Inc.
5  *
6  *   This file is part of Lustre, http://www.lustre.org.
7  *
8  *   Lustre is free software; you can redistribute it and/or
9  *   modify it under the terms of version 2 of the GNU General Public
10  *   License as published by the Free Software Foundation.
11  *
12  *   Lustre is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with Lustre; if not, write to the Free Software
19  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  */
21
22 #ifndef __LINUX_SEC_H_
23 #define __LINUX_SEC_H_
24
25 //#include <linux/lustre_idl.h>
26
27 enum ptlrpcs_major_flavors {
28         PTLRPCS_FLVR_MAJOR_NULL         = 0,
29         PTLRPCS_FLVR_MAJOR_GSS          = 1,
30         PTLRPCS_FLVR_MAJOR_MAX,
31 };
32
33 enum ptlrpcs_null_minor_flavors {
34         PTLRPCS_FLVR_MINOR_NULL         = 0,
35         PTLRPCS_FLVR_MINOR_NULL_MAX,
36 };
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,
41 };
42
43 enum ptlrpcs_security_type {
44         PTLRPCS_SVC_NONE                = 0,    /* no security */
45         PTLRPCS_SVC_AUTH                = 1,    /* authentication */
46         PTLRPCS_SVC_PRIV                = 2,    /* privacy */
47         PTLRPCS_SVC_MAX,
48 };
49
50 /*
51  * flavor compose/extract
52  */
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)
57
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))
62
63 #define SEC_MAKE_SUBFLAVOR(minor, svc)                          \
64         (((__u32)(svc) << SEC_FLAVOR_SVC_OFFSET) |              \
65          ((__u32)(minor) << SEC_FLAVOR_MINOR_OFFSET))
66
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)
75
76 /*
77  * general gss flavors
78  */
79 #define PTLRPCS_FLVR_GSS_NONE                           \
80         SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS,         \
81                         PTLRPCS_FLVR_MINOR_GSS_NONE,    \
82                         PTLRPCS_SVC_NONE)
83 #define PTLRPCS_FLVR_GSS_AUTH                           \
84         SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS,         \
85                         PTLRPCS_FLVR_MINOR_GSS_NONE,    \
86                         PTLRPCS_SVC_AUTH)
87 #define PTLRPCS_FLVR_GSS_PRIV                           \
88         SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS,         \
89                         PTLRPCS_FLVR_MINOR_GSS_NONE,    \
90                         PTLRPCS_SVC_PRIV)
91
92 /*
93  * gss subflavors
94  */
95 #define PTLRPCS_SUBFLVR_KRB5                            \
96         SEC_MAKE_SUBFLAVOR(PTLRPCS_FLVR_MINOR_GSS_KRB5, \
97                            PTLRPCS_SVC_NONE)
98 #define PTLRPCS_SUBFLVR_KRB5I                           \
99         SEC_MAKE_SUBFLAVOR(PTLRPCS_FLVR_MINOR_GSS_KRB5, \
100                            PTLRPCS_SVC_AUTH)
101 #define PTLRPCS_SUBFLVR_KRB5P                           \
102         SEC_MAKE_SUBFLAVOR(PTLRPCS_FLVR_MINOR_GSS_KRB5, \
103                            PTLRPCS_SVC_PRIV)
104
105 /*
106  * "end user" flavors
107  */
108 #define PTLRPCS_FLVR_NULL                               \
109         SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_NULL,        \
110                         PTLRPCS_FLVR_MINOR_NULL,        \
111                         PTLRPCS_SVC_NONE)
112 #define PTLRPCS_FLVR_KRB5                               \
113         SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS,         \
114                         PTLRPCS_FLVR_MINOR_GSS_KRB5,    \
115                         PTLRPCS_SVC_NONE)
116 #define PTLRPCS_FLVR_KRB5I                              \
117         SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS,         \
118                         PTLRPCS_FLVR_MINOR_GSS_KRB5,    \
119                         PTLRPCS_SVC_AUTH)
120 #define PTLRPCS_FLVR_KRB5P                              \
121         SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS,         \
122                         PTLRPCS_FLVR_MINOR_GSS_KRB5,    \
123                         PTLRPCS_SVC_PRIV)
124
125 #define PTLRPCS_FLVR_INVALID    (-1)
126
127 __u32 ptlrpcs_name2flavor(const char *name);
128 char *ptlrpcs_flavor2name(__u32 flavor);
129
130
131 #ifdef __KERNEL__
132
133 /* forward declaration */
134 struct obd_import;
135 struct ptlrpc_request;
136 struct ptlrpc_cred;
137 struct ptlrpc_credops;
138 struct ptlrpc_sec;
139 struct ptlrpc_secops;
140
141
142 typedef struct {
143         struct list_head        list;
144         __u32                   flavor;
145 } deny_sec_t;
146
147 /*
148  * This header is prepended at any on-wire ptlrpc packets
149  */
150 struct ptlrpcs_wire_hdr {
151         __u32   flavor;
152         __u32   unused;
153         __u32   msg_len;
154         __u32   sec_len;
155 };
156
157 static inline
158 struct ptlrpcs_wire_hdr *buf_to_sec_hdr(void *buf)
159 {
160         return (struct ptlrpcs_wire_hdr *) buf;
161 }
162
163 static inline
164 struct lustre_msg *buf_to_lustre_msg(void *buf)
165 {
166         return (struct lustre_msg *)
167                ((char *) buf + sizeof(struct ptlrpcs_wire_hdr));
168 }
169
170 static inline
171 __u8 *buf_to_sec_data(void *buf)
172 {
173         struct ptlrpcs_wire_hdr *hdr = buf_to_sec_hdr(buf);
174         return (__u8 *) (buf + sizeof(*hdr) + hdr->msg_len);
175 }
176
177 #define PTLRPC_SEC_GSS_VERSION (1)
178
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,
185 };
186                                                                                                                         
187 enum ptlrpcs_gss_svc {
188         PTLRPCS_GSS_SVC_NONE            = 1,
189         PTLRPCS_GSS_SVC_INTEGRITY       = 2,
190         PTLRPCS_GSS_SVC_PRIVACY         = 3,
191 };
192
193 enum ptlrpcs_error {
194         PTLRPCS_OK                      = 0,
195         PTLRPCS_BADCRED                 = 1,
196         PTLRPCS_REJECTEDCRED            = 2,
197         PTLRPCS_BADVERF                 = 3,
198         PTLRPCS_REJECTEDVERF            = 4,
199         PTLRPCS_TOOWEAK                 = 5,
200         /* GSS errors */
201         PTLRPCS_GSS_CREDPROBLEM         = 13,
202         PTLRPCS_GSS_CTXPROBLEM          = 14,
203 };
204
205 struct vfs_cred {
206         __u64                   vc_pag;
207         uid_t                   vc_uid;
208         gid_t                   vc_gid;
209         struct group_info      *vc_ginfo;
210 };
211
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);
224 };
225
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.) */
229
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)
233
234 #define PTLRPC_CRED_FLAGS_MASK          (PTLRPC_CRED_UPTODATE |         \
235                                          PTLRPC_CRED_DEAD |             \
236                                          PTLRPC_CRED_ERROR)
237
238 struct ptlrpc_cred {
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 */
246         __u64                   pc_pag;
247         uid_t                   pc_uid;
248 };
249
250 struct ptlrpc_secops {
251         struct ptlrpc_sec *   (*create_sec)    (__u32 flavor,
252                                                 const char *pipe_dir,
253                                                 void *pipe_data);
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,
271                                                  int msgsize);
272         int                   (*est_rep_payload)(struct ptlrpc_sec *sec,
273                                                  struct ptlrpc_request *req,
274                                                  int msgsize);
275 };
276
277 struct ptlrpc_sec_type {
278         struct module          *pst_owner;
279         char                   *pst_name;
280         atomic_t                pst_inst;       /* instance, debug only */
281         __u32                   pst_flavor;     /* major flavor */
282         struct ptlrpc_secops   *pst_ops;
283 };
284
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 */
288
289 #define PTLRPC_CREDCACHE_NR     8
290 #define PTLRPC_CREDCACHE_MASK   (PTLRPC_CREDCACHE_NR - 1)
291
292 struct ptlrpc_sec {
293         struct ptlrpc_sec_type *ps_type;
294         struct list_head        ps_credcache[PTLRPC_CREDCACHE_NR];
295         spinlock_t              ps_lock;        /* protect cred cache */
296         __u32                   ps_flavor;
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;
304 };
305
306 /* sec.c */
307 int  ptlrpcs_register(struct ptlrpc_sec_type *type);
308 int  ptlrpcs_unregister(struct ptlrpc_sec_type *type);
309
310 struct ptlrpc_sec * ptlrpcs_sec_create(__u32 flavor,
311                                        unsigned long flags,
312                                        struct obd_import *import,
313                                        const char *pipe_dir,
314                                        void *pipe_data);
315 void ptlrpcs_sec_put(struct ptlrpc_sec *sec);
316 void ptlrpcs_sec_invalidate_cache(struct ptlrpc_sec *sec);
317
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);
321
322 static inline void ptlrpcs_cred_get(struct ptlrpc_cred *cred)
323 {
324         LASSERT(atomic_read(&cred->pc_refcount));
325         atomic_inc(&cred->pc_refcount);
326 }
327
328 static inline int ptlrpcs_cred_refresh(struct ptlrpc_cred *cred)
329 {
330         LASSERT(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);
335 }
336
337 static inline int ptlrpcs_cred_is_uptodate(struct ptlrpc_cred *cred)
338 {
339         smp_mb();
340         return ((cred->pc_flags & PTLRPC_CRED_FLAGS_MASK) ==
341                 PTLRPC_CRED_UPTODATE);
342 }
343
344 static inline int ptlrpcs_cred_is_dead(struct ptlrpc_cred *cred)
345 {
346         smp_mb();
347         return ((cred->pc_flags & (PTLRPC_CRED_DEAD | PTLRPC_CRED_ERROR)) != 0);
348 }
349
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);   \
354         }
355
356 static inline int ptlrpcs_cred_check_uptodate(struct ptlrpc_cred *cred)
357 {
358         LASSERT(atomic_read(&cred->pc_refcount));
359
360         if (!ptlrpcs_cred_is_uptodate(cred))
361                 return 1;
362
363         if (cred->pc_expire == 0)
364                 return 0;
365         if (time_after(cred->pc_expire, get_seconds()))
366                 return 0;
367         ptlrpcs_cred_expire(cred);
368         return 1;
369 }
370
371 static inline int ptlrpcs_est_req_payload(struct ptlrpc_request *req,
372                                           int datasize)
373 {
374         struct ptlrpc_sec *sec = req->rq_cred->pc_sec;
375         struct ptlrpc_secops *ops;
376
377         LASSERT(sec);
378         LASSERT(sec->ps_type);
379         LASSERT(sec->ps_type->pst_ops);
380
381         ops = sec->ps_type->pst_ops;
382         if (ops->est_req_payload)
383                 return ops->est_req_payload(sec, req, datasize);
384         else
385                 return 0;
386 }
387
388 static inline int ptlrpcs_est_rep_payload(struct ptlrpc_request *req,
389                                           int datasize)
390 {
391         struct ptlrpc_sec *sec = req->rq_cred->pc_sec;
392         struct ptlrpc_secops *ops;
393
394         LASSERT(sec);
395         LASSERT(sec->ps_type);
396         LASSERT(sec->ps_type->pst_ops);
397
398         ops = sec->ps_type->pst_ops;
399         if (ops->est_rep_payload)
400                 return ops->est_rep_payload(sec, req, datasize);
401         else
402                 return 0;
403 }
404
405 static inline int add_deny_security(char *sec, struct list_head *head)
406 {
407         deny_sec_t     *p_deny_sec = NULL;
408         int             rc = 0;
409
410         LASSERT(sec != NULL);
411
412         OBD_ALLOC(p_deny_sec, sizeof(*p_deny_sec));
413         if (p_deny_sec == NULL)
414                 return -ENOMEM;
415
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);
419                 rc = -EINVAL;
420                 goto out;
421         }
422
423         list_add_tail(&p_deny_sec->list, head);
424 out:
425         if (rc) {
426                 if (p_deny_sec)
427                         OBD_FREE(p_deny_sec, sizeof(*p_deny_sec));
428         }
429         return rc;
430 }
431
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);
438
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);
448
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);
453
454 /* sec_null.c */
455 int ptlrpcs_null_init(void);
456 int ptlrpcs_null_exit(void);
457
458 /**********************************************************
459  * Server side stuff
460  **********************************************************/
461
462 struct ptlrpc_reply_state;
463
464 struct ptlrpc_svcsec {
465         struct module           *pss_owner;
466         char                    *pss_name;
467         __u32                    pss_flavor;    /* major flavor */
468         int                      pss_sec_size;
469
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,
475                                                int msgsize);
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);
480 };
481
482 #define SVC_OK          1
483 #define SVC_COMPLETE    2
484 #define SVC_DROP        3
485 #define SVC_LOGIN       4
486 #define SVC_LOGOUT      5
487
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);
495
496 struct ptlrpc_svcsec * svcsec_get(struct ptlrpc_svcsec *sec);
497 void svcsec_put(struct ptlrpc_svcsec *sec);
498
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);
503
504 /* svcsec_null.c */
505 int svcsec_null_init(void);
506 int svcsec_null_exit(void);
507
508 /* capability */
509 #include <linux/crypto.h>
510
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"
516
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));
526
527 struct client_capa {
528         struct inode             *inode;      /* this should be always valid
529                                                * if c_refc > 0 */
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 */
533 };
534
535 struct filter_capa {
536         int                       bvalid;     /* black key here valid or not */
537         __u32                     bkeyid;     /* black key id */
538         __u8                      bhmac[CAPA_DIGEST_SIZE]; /* black key */
539 };
540
541 struct obd_capa {
542         struct hlist_node         c_hash;
543         struct list_head          c_list;
544
545         struct lustre_capa        c_capa;        /* capa */
546         int                       c_type;
547         atomic_t                  c_refc;
548
549         union {
550                 struct client_capa       client;
551                 struct filter_capa       filter;
552         } u;
553 };
554
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
560
561 enum lustre_capa_type {
562         CLIENT_CAPA = 0,
563         MDS_CAPA    = 1,
564         FILTER_CAPA = 2,
565 };
566
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;
571
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);
587
588 #define CAPA_EXPIRY_SHIFT 10 /* 1024 sec */
589 #define CAPA_EXPIRY       (1UL << PAGE_SHIFT)
590 #define CAPA_EXPIRY_MASK  (~(CAPA_EXPIRY-1))
591
592 #define CAPA_PRE_EXPIRY_NOROUND 3       /* sec */
593 #define CAPA_PRE_EXPIRY         300     /* sec */
594
595 /* struct lustre_capa.lc_flags */
596 #define CAPA_FL_NOROUND   0x001 /* capa expiry not rounded */
597
598 static inline unsigned long capa_pre_expiry(struct lustre_capa *capa)
599 {
600         return (capa->lc_flags & CAPA_FL_NOROUND) ? 
601                         CAPA_PRE_EXPIRY_NOROUND : CAPA_PRE_EXPIRY;
602 }
603
604 static inline __u64
605 round_expiry(__u32 timeout)
606 {
607         struct timeval tv;
608         __u64 expiry;
609
610         do_gettimeofday(&tv);
611         expiry = tv.tv_sec + timeout;
612
613         if (timeout > CAPA_EXPIRY)
614                 expiry = (expiry + CAPA_EXPIRY - 1) & CAPA_EXPIRY_MASK;
615
616         return expiry;
617 }
618
619 static inline int
620 capa_key_cmp(struct lustre_capa_key *k1, struct lustre_capa_key *k2)
621 {
622         return le32_to_cpu(k1->lk_keyid) - le32_to_cpu(k2->lk_keyid);
623 }
624
625 static inline unsigned long
626 expiry_to_jiffies(__u64 expiry)
627 {
628         /* sec -> jiffies */
629         struct timeval tv;
630
631         do_gettimeofday(&tv);
632         return jiffies + ((unsigned long)expiry - tv.tv_sec) * HZ;
633 }
634
635 #endif /* __KERNEL__ */
636
637 struct mds_capa_key {
638         struct list_head        k_list;
639
640         struct lustre_capa_key *k_key;
641         struct obd_device      *k_obd;
642 };
643
644 struct filter_capa_key {
645         struct list_head        k_list;
646
647         struct lustre_capa_key  k_key;
648 };
649
650 #endif /* __LINUX_SEC_H_ */