Whamcloud - gitweb
on OSS compare the whole capa structure because we might have 2 capa only
[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 enum ptlrpcs_major_flavors {
26         PTLRPCS_FLVR_MAJOR_NULL         = 0,
27         PTLRPCS_FLVR_MAJOR_GSS          = 1,
28         PTLRPCS_FLVR_MAJOR_MAX,
29 };
30
31 enum ptlrpcs_null_minor_flavors {
32         PTLRPCS_FLVR_MINOR_NULL         = 0,
33         PTLRPCS_FLVR_MINOR_NULL_MAX,
34 };
35
36 enum ptlrpcs_gss_minor_flavors {
37         PTLRPCS_FLVR_MINOR_GSS_NONE     = 0,
38         PTLRPCS_FLVR_MINOR_GSS_KRB5     = 1,
39         PTLRPCS_FLVR_MINOR_GSS_MAX,
40 };
41
42 enum ptlrpcs_security_type {
43         PTLRPCS_SVC_NONE                = 0,    /* no security */
44         PTLRPCS_SVC_AUTH                = 1,    /* authentication */
45         PTLRPCS_SVC_PRIV                = 2,    /* privacy */
46         PTLRPCS_SVC_MAX,
47 };
48
49 /*
50  * flavor compose/extract
51  */
52 #define SEC_FLAVOR_MAJOR_OFFSET         (24)
53 #define SEC_FLAVOR_RESERVE_OFFSET       (16)
54 #define SEC_FLAVOR_SVC_OFFSET           (8)
55 #define SEC_FLAVOR_MINOR_OFFSET         (0)
56
57 #define SEC_MAKE_FLAVOR(major, minor, svc)                      \
58         (((__u32)(major) << SEC_FLAVOR_MAJOR_OFFSET) |          \
59          ((__u32)(svc) << SEC_FLAVOR_SVC_OFFSET) |              \
60          ((__u32)(minor) << SEC_FLAVOR_MINOR_OFFSET))
61
62 #define SEC_MAKE_SUBFLAVOR(minor, svc)                          \
63         (((__u32)(svc) << SEC_FLAVOR_SVC_OFFSET) |              \
64          ((__u32)(minor) << SEC_FLAVOR_MINOR_OFFSET))
65
66 #define SEC_FLAVOR_MAJOR(flavor)                                        \
67         ((((__u32)(flavor)) >> SEC_FLAVOR_MAJOR_OFFSET) & 0xFF)
68 #define SEC_FLAVOR_MINOR(flavor)                                        \
69         ((((__u32)(flavor)) >> SEC_FLAVOR_MINOR_OFFSET) & 0xFF)
70 #define SEC_FLAVOR_SVC(flavor)                                          \
71         ((((__u32)(flavor)) >> SEC_FLAVOR_SVC_OFFSET) & 0xFF)
72 #define SEC_FLAVOR_SUB(flavor)                                          \
73         ((((__u32)(flavor)) >> SEC_FLAVOR_MINOR_OFFSET) & 0xFFFF)
74
75 /*
76  * general gss flavors
77  */
78 #define PTLRPCS_FLVR_GSS_NONE                           \
79         SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS,         \
80                         PTLRPCS_FLVR_MINOR_GSS_NONE,    \
81                         PTLRPCS_SVC_NONE)
82 #define PTLRPCS_FLVR_GSS_AUTH                           \
83         SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS,         \
84                         PTLRPCS_FLVR_MINOR_GSS_NONE,    \
85                         PTLRPCS_SVC_AUTH)
86 #define PTLRPCS_FLVR_GSS_PRIV                           \
87         SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS,         \
88                         PTLRPCS_FLVR_MINOR_GSS_NONE,    \
89                         PTLRPCS_SVC_PRIV)
90
91 /*
92  * gss subflavors
93  */
94 #define PTLRPCS_SUBFLVR_KRB5                            \
95         SEC_MAKE_SUBFLAVOR(PTLRPCS_FLVR_MINOR_GSS_KRB5, \
96                            PTLRPCS_SVC_NONE)
97 #define PTLRPCS_SUBFLVR_KRB5I                           \
98         SEC_MAKE_SUBFLAVOR(PTLRPCS_FLVR_MINOR_GSS_KRB5, \
99                            PTLRPCS_SVC_AUTH)
100 #define PTLRPCS_SUBFLVR_KRB5P                           \
101         SEC_MAKE_SUBFLAVOR(PTLRPCS_FLVR_MINOR_GSS_KRB5, \
102                            PTLRPCS_SVC_PRIV)
103
104 /*
105  * "end user" flavors
106  */
107 #define PTLRPCS_FLVR_NULL                               \
108         SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_NULL,        \
109                         PTLRPCS_FLVR_MINOR_NULL,        \
110                         PTLRPCS_SVC_NONE)
111 #define PTLRPCS_FLVR_KRB5                               \
112         SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS,         \
113                         PTLRPCS_FLVR_MINOR_GSS_KRB5,    \
114                         PTLRPCS_SVC_NONE)
115 #define PTLRPCS_FLVR_KRB5I                              \
116         SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS,         \
117                         PTLRPCS_FLVR_MINOR_GSS_KRB5,    \
118                         PTLRPCS_SVC_AUTH)
119 #define PTLRPCS_FLVR_KRB5P                              \
120         SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS,         \
121                         PTLRPCS_FLVR_MINOR_GSS_KRB5,    \
122                         PTLRPCS_SVC_PRIV)
123
124 #define PTLRPCS_FLVR_INVALID    (-1)
125
126 __u32 ptlrpcs_name2flavor(const char *name);
127 char *ptlrpcs_flavor2name(__u32 flavor);
128
129
130 /* forward declaration */
131 struct obd_import;
132 struct ptlrpc_request;
133 struct ptlrpc_cred;
134 struct ptlrpc_credops;
135 struct ptlrpc_sec;
136 struct ptlrpc_secops;
137
138 typedef struct {
139         struct list_head        list;
140         __u32                   flavor;
141 } deny_sec_t;
142
143 /*
144  * This header is prepended at any on-wire ptlrpc packets
145  */
146 struct ptlrpcs_wire_hdr {
147         __u32   flavor;
148         __u32   unused;
149         __u32   msg_len;
150         __u32   sec_len;
151 };
152
153 static inline
154 struct ptlrpcs_wire_hdr *buf_to_sec_hdr(void *buf)
155 {
156         return (struct ptlrpcs_wire_hdr *) buf;
157 }
158
159 static inline
160 struct lustre_msg *buf_to_lustre_msg(void *buf)
161 {
162         return (struct lustre_msg *)
163                ((char *) buf + sizeof(struct ptlrpcs_wire_hdr));
164 }
165
166 static inline
167 __u8 *buf_to_sec_data(void *buf)
168 {
169         struct ptlrpcs_wire_hdr *hdr = buf_to_sec_hdr(buf);
170         return (__u8 *) (buf + sizeof(*hdr) + hdr->msg_len);
171 }
172
173 #define PTLRPC_SEC_GSS_VERSION (1)
174
175 enum ptlrpcs_gss_proc {
176         PTLRPCS_GSS_PROC_DATA           = 0,
177         PTLRPCS_GSS_PROC_INIT           = 1,
178         PTLRPCS_GSS_PROC_CONTINUE_INIT  = 2,
179         PTLRPCS_GSS_PROC_DESTROY        = 3,
180         PTLRPCS_GSS_PROC_ERR            = 4,
181 };
182                                                                                                                         
183 enum ptlrpcs_gss_svc {
184         PTLRPCS_GSS_SVC_NONE            = 1,
185         PTLRPCS_GSS_SVC_INTEGRITY       = 2,
186         PTLRPCS_GSS_SVC_PRIVACY         = 3,
187 };
188
189 enum ptlrpcs_error {
190         PTLRPCS_OK                      = 0,
191         PTLRPCS_BADCRED                 = 1,
192         PTLRPCS_REJECTEDCRED            = 2,
193         PTLRPCS_BADVERF                 = 3,
194         PTLRPCS_REJECTEDVERF            = 4,
195         PTLRPCS_TOOWEAK                 = 5,
196         /* GSS errors */
197         PTLRPCS_GSS_CREDPROBLEM         = 13,
198         PTLRPCS_GSS_CTXPROBLEM          = 14,
199 };
200
201 struct vfs_cred {
202         __u64                   vc_pag;
203         uid_t                   vc_uid;
204         gid_t                   vc_gid;
205         struct group_info      *vc_ginfo;
206 };
207
208 struct ptlrpc_credops {
209         int     (*match)  (struct ptlrpc_cred *cred, struct vfs_cred *vcred);
210         int     (*refresh)(struct ptlrpc_cred *cred);
211         void    (*destroy)(struct ptlrpc_cred *cred);
212         int     (*sign)   (struct ptlrpc_cred *cred,
213                            struct ptlrpc_request *req);
214         int     (*verify) (struct ptlrpc_cred *cred,
215                            struct ptlrpc_request *req);
216         int     (*seal)   (struct ptlrpc_cred *cred,
217                            struct ptlrpc_request *req);
218         int     (*unseal) (struct ptlrpc_cred *cred,
219                            struct ptlrpc_request *req);
220 };
221
222 #define PTLRPC_CRED_UPTODATE_BIT        0 /* uptodate */
223 #define PTLRPC_CRED_DEAD_BIT            1 /* mark expired gracefully */
224 #define PTLRPC_CRED_ERROR_BIT           2 /* fatal error (refresh, etc.) */
225
226 #define PTLRPC_CRED_UPTODATE            (1 << PTLRPC_CRED_UPTODATE_BIT)
227 #define PTLRPC_CRED_DEAD                (1 << PTLRPC_CRED_DEAD_BIT)
228 #define PTLRPC_CRED_ERROR               (1 << PTLRPC_CRED_ERROR_BIT)
229
230 #define PTLRPC_CRED_FLAGS_MASK          (PTLRPC_CRED_UPTODATE |         \
231                                          PTLRPC_CRED_DEAD |             \
232                                          PTLRPC_CRED_ERROR)
233
234 struct ptlrpc_cred {
235         struct list_head        pc_hash;   /* linked into hash table */
236         atomic_t                pc_refcount;
237         struct ptlrpc_sec      *pc_sec;
238         struct ptlrpc_credops  *pc_ops;
239         unsigned long           pc_expire;
240         unsigned long           pc_flags;
241         /* XXX maybe should not be here */
242         __u64                   pc_pag;
243         uid_t                   pc_uid;
244 };
245
246 struct ptlrpc_secops {
247         struct ptlrpc_sec *   (*create_sec)    (__u32 flavor,
248                                                 const char *pipe_dir,
249                                                 void *pipe_data);
250         void                  (*destroy_sec)   (struct ptlrpc_sec *sec);
251         struct ptlrpc_cred *  (*create_cred)   (struct ptlrpc_sec *sec,
252                                                 struct vfs_cred *vcred);
253         /* buffer manipulation */
254         int                   (*alloc_reqbuf)  (struct ptlrpc_sec *sec,
255                                                 struct ptlrpc_request *req,
256                                                 int lustre_msg_size);
257         int                   (*alloc_repbuf)  (struct ptlrpc_sec *sec,
258                                                 struct ptlrpc_request *req,
259                                                 int lustre_msg_size);
260         void                  (*free_reqbuf)   (struct ptlrpc_sec *sec,
261                                                 struct ptlrpc_request *req);
262         void                  (*free_repbuf)   (struct ptlrpc_sec *sec,
263                                                 struct ptlrpc_request *req);
264         /* security payload size estimation */
265         int                   (*est_req_payload)(struct ptlrpc_sec *sec,
266                                                  struct ptlrpc_request *req,
267                                                  int msgsize);
268         int                   (*est_rep_payload)(struct ptlrpc_sec *sec,
269                                                  struct ptlrpc_request *req,
270                                                  int msgsize);
271 };
272
273 struct ptlrpc_sec_type {
274         struct module          *pst_owner;
275         char                   *pst_name;
276         atomic_t                pst_inst;       /* instance, debug only */
277         __u32                   pst_flavor;     /* major flavor */
278         struct ptlrpc_secops   *pst_ops;
279 };
280
281 #define PTLRPC_SEC_FL_MDS               0x0001 /* outgoing from MDS */
282 #define PTLRPC_SEC_FL_REVERSE           0x0002 /* reverse sec */
283 #define PTLRPC_SEC_FL_PAG               0x0004 /* enable PAG */
284 #define PTLRPC_SEC_FL_OSS               0x0008 /* outgoing to OSS XXX */
285
286 #define PTLRPC_CREDCACHE_NR     8
287 #define PTLRPC_CREDCACHE_MASK   (PTLRPC_CREDCACHE_NR - 1)
288
289 struct ptlrpc_sec {
290         struct ptlrpc_sec_type *ps_type;
291         struct list_head        ps_credcache[PTLRPC_CREDCACHE_NR];
292         spinlock_t              ps_lock;        /* protect cred cache */
293         __u32                   ps_flavor;
294         atomic_t                ps_refcount;
295         atomic_t                ps_credcount;
296         struct obd_import      *ps_import;
297         /* actual security model need initialize following fields */
298         unsigned long           ps_expire;      /* cache expire interval */
299         unsigned long           ps_nextgc;      /* next gc time */
300         unsigned long           ps_flags;
301 };
302
303 /* sec.c */
304 int  ptlrpcs_register(struct ptlrpc_sec_type *type);
305 int  ptlrpcs_unregister(struct ptlrpc_sec_type *type);
306
307 struct ptlrpc_sec * ptlrpcs_sec_create(__u32 flavor,
308                                        unsigned long flags,
309                                        struct obd_import *import,
310                                        const char *pipe_dir,
311                                        void *pipe_data);
312 void ptlrpcs_sec_put(struct ptlrpc_sec *sec);
313 void ptlrpcs_sec_invalidate_cache(struct ptlrpc_sec *sec);
314
315 struct ptlrpc_cred * ptlrpcs_cred_lookup(struct ptlrpc_sec *sec,
316                                          struct vfs_cred *vcred);
317 void ptlrpcs_cred_put(struct ptlrpc_cred *cred, int sync);
318
319 static inline void ptlrpcs_cred_get(struct ptlrpc_cred *cred)
320 {
321         LASSERT(atomic_read(&cred->pc_refcount));
322         atomic_inc(&cred->pc_refcount);
323 }
324
325 static inline int ptlrpcs_cred_refresh(struct ptlrpc_cred *cred)
326 {
327         LASSERT(cred);
328         LASSERT(atomic_read(&cred->pc_refcount));
329         LASSERT(cred->pc_ops);
330         LASSERT(cred->pc_ops->refresh);
331         return cred->pc_ops->refresh(cred);
332 }
333
334 static inline int ptlrpcs_cred_is_uptodate(struct ptlrpc_cred *cred)
335 {
336         smp_mb();
337         return ((cred->pc_flags & PTLRPC_CRED_FLAGS_MASK) ==
338                 PTLRPC_CRED_UPTODATE);
339 }
340
341 static inline int ptlrpcs_cred_is_dead(struct ptlrpc_cred *cred)
342 {
343         smp_mb();
344         return ((cred->pc_flags & (PTLRPC_CRED_DEAD | PTLRPC_CRED_ERROR)) != 0);
345 }
346
347 #define ptlrpcs_cred_expire(cred)                                       \
348         if (!test_and_set_bit(PTLRPC_CRED_DEAD_BIT, &cred->pc_flags)) { \
349                 CWARN("cred %p: get expired\n", cred);                  \
350                 clear_bit(PTLRPC_CRED_UPTODATE_BIT, &cred->pc_flags);   \
351         }
352
353 static inline int ptlrpcs_cred_check_uptodate(struct ptlrpc_cred *cred)
354 {
355         LASSERT(atomic_read(&cred->pc_refcount));
356
357         if (!ptlrpcs_cred_is_uptodate(cred))
358                 return 1;
359
360         if (cred->pc_expire == 0)
361                 return 0;
362         if (time_after(cred->pc_expire, get_seconds()))
363                 return 0;
364         ptlrpcs_cred_expire(cred);
365         return 1;
366 }
367
368 static inline int ptlrpcs_est_req_payload(struct ptlrpc_request *req,
369                                           int datasize)
370 {
371         struct ptlrpc_sec *sec = req->rq_cred->pc_sec;
372         struct ptlrpc_secops *ops;
373
374         LASSERT(sec);
375         LASSERT(sec->ps_type);
376         LASSERT(sec->ps_type->pst_ops);
377
378         ops = sec->ps_type->pst_ops;
379         if (ops->est_req_payload)
380                 return ops->est_req_payload(sec, req, datasize);
381         else
382                 return 0;
383 }
384
385 static inline int ptlrpcs_est_rep_payload(struct ptlrpc_request *req,
386                                           int datasize)
387 {
388         struct ptlrpc_sec *sec = req->rq_cred->pc_sec;
389         struct ptlrpc_secops *ops;
390
391         LASSERT(sec);
392         LASSERT(sec->ps_type);
393         LASSERT(sec->ps_type->pst_ops);
394
395         ops = sec->ps_type->pst_ops;
396         if (ops->est_rep_payload)
397                 return ops->est_rep_payload(sec, req, datasize);
398         else
399                 return 0;
400 }
401
402 static inline int add_deny_security(char *sec, struct list_head *head)
403 {
404         deny_sec_t     *p_deny_sec = NULL;
405         int             rc = 0;
406
407         LASSERT(sec != NULL);
408
409         OBD_ALLOC(p_deny_sec, sizeof(*p_deny_sec));
410         if (p_deny_sec == NULL)
411                 return -ENOMEM;
412
413         p_deny_sec->flavor = ptlrpcs_name2flavor(sec);
414         if (p_deny_sec->flavor == PTLRPCS_FLVR_INVALID) {
415                 CERROR("unrecognized security type %s\n", (char*) sec);
416                 rc = -EINVAL;
417                 goto out;
418         }
419
420         list_add_tail(&p_deny_sec->list, head);
421 out:
422         if (rc) {
423                 if (p_deny_sec)
424                         OBD_FREE(p_deny_sec, sizeof(*p_deny_sec));
425         }
426         return rc;
427 }
428
429 int ptlrpcs_cli_wrap_request(struct ptlrpc_request *req);
430 int ptlrpcs_cli_unwrap_reply(struct ptlrpc_request *req);
431 int ptlrpcs_cli_alloc_reqbuf(struct ptlrpc_request *req, int msgsize);
432 int ptlrpcs_cli_alloc_repbuf(struct ptlrpc_request *req, int msgsize);
433 void ptlrpcs_cli_free_reqbuf(struct ptlrpc_request *req);
434 void ptlrpcs_cli_free_repbuf(struct ptlrpc_request *req);
435
436 /* higher interface */
437 int  ptlrpcs_import_get_sec(struct obd_import *imp);
438 void ptlrpcs_import_drop_sec(struct obd_import *imp);
439 void ptlrpcs_import_flush_current_creds(struct obd_import *imp);
440 int  ptlrpcs_req_get_cred(struct ptlrpc_request *req);
441 void ptlrpcs_req_drop_cred(struct ptlrpc_request *req);
442 int  ptlrpcs_req_replace_dead_cred(struct ptlrpc_request *req);
443 int  ptlrpcs_req_refresh_cred(struct ptlrpc_request *req);
444 int ptlrpcs_check_cred(struct obd_import *imp);
445
446 /* internal helpers */
447 int sec_alloc_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req,
448                      int msgsize, int secsize);
449 void sec_free_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req);
450
451 /* sec_null.c */
452 int ptlrpcs_null_init(void);
453 int ptlrpcs_null_exit(void);
454
455 /**********************************************************
456  * Server side stuff
457  **********************************************************/
458
459 struct ptlrpc_reply_state;
460
461 struct ptlrpc_svcsec {
462         struct module           *pss_owner;
463         char                    *pss_name;
464         __u32                    pss_flavor;    /* major flavor */
465         int                      pss_sec_size;
466
467         int                    (*accept)      (struct ptlrpc_request *req,
468                                                enum ptlrpcs_error *res);
469         int                    (*authorize)   (struct ptlrpc_request *req);
470         int                    (*alloc_repbuf)(struct ptlrpc_svcsec *svcsec,
471                                                struct ptlrpc_request *req,
472                                                int msgsize);
473         void                   (*free_repbuf) (struct ptlrpc_svcsec *svcsec,
474                                                struct ptlrpc_reply_state *rs);
475         void                   (*cleanup_req) (struct ptlrpc_svcsec *svcsec,
476                                                struct ptlrpc_request *req);
477 };
478
479 #define SVC_OK          1
480 #define SVC_COMPLETE    2
481 #define SVC_DROP        3
482 #define SVC_LOGIN       4
483 #define SVC_LOGOUT      5
484
485 int svcsec_register(struct ptlrpc_svcsec *ss);
486 int svcsec_unregister(struct ptlrpc_svcsec *ss);
487 int svcsec_accept(struct ptlrpc_request *req, enum ptlrpcs_error *res);
488 int svcsec_authorize(struct ptlrpc_request *req);
489 int svcsec_alloc_repbuf(struct ptlrpc_svcsec *svcsec,
490                         struct ptlrpc_request *req, int msgsize);
491 void svcsec_cleanup_req(struct ptlrpc_request *req);
492
493 struct ptlrpc_svcsec * svcsec_get(struct ptlrpc_svcsec *sec);
494 void svcsec_put(struct ptlrpc_svcsec *sec);
495
496 /* internal helpers */
497 int svcsec_alloc_reply_state(struct ptlrpc_request *req,
498                              int msgsize, int secsize);
499 void svcsec_free_reply_state(struct ptlrpc_reply_state *rs);
500
501 /* svcsec_null.c */
502 int svcsec_null_init(void);
503 int svcsec_null_exit(void);
504
505 /* capability */
506 #ifdef __KERNEL__
507 #include <linux/crypto.h>
508 #endif
509
510 #define NR_CAPAHASH 32
511 #define CAPA_TIMEOUT 1800                /* sec, == 30 min */
512 #define CAPA_KEY_TIMEOUT (24 * 60 * 60)  /* sec, == 1 day */
513 #define CAPA_CACHE_SIZE 3000             /* for MDS & OST */
514 #define CAPA_HMAC_ALG "sha1"
515
516 /* capa ops */
517 #define CAPA_WRITE      MAY_WRITE       /* 2 */
518 #define CAPA_READ       MAY_READ        /* 4 */
519 #define CAPA_TRUNC      8
520
521 struct lustre_capa_data {
522         __u32   lc_uid;       /* uid, mapped uid */
523         __u32   lc_ruid;      /* remote uid on client */
524         __u32   lc_op;        /* operations allowed */
525         __u32   lc_igen;      /* inode generation */
526         __u64   lc_ino;       /* inode# */
527         __u32   lc_mdsid;     /* mds# */
528         __u32   lc_keyid;     /* key used for the capability */
529         __u64   lc_expiry;    /* expiry time: servers have clocks */
530         __u32   lc_flags;     /* security features for capability */
531 } __attribute__((packed));
532
533 struct client_capa {
534         struct inode             *inode;      
535         struct lustre_handle      handle;     /* handle of mds_file_data */
536         struct list_head          lli_list;   /* link to lli_capas */
537 #if 0   /* TODO: support multi mount point */
538         struct list_head         *list;       /* the capa list belong to this client */
539         struct timer_list        *timer;      /* timer belong to this client */
540 #endif
541 };
542
543 struct filter_capa {
544         int                       bvalid;     /* black key here valid or not */
545         __u32                     bkeyid;     /* black key id */
546         __u8                      bhmac[CAPA_DIGEST_SIZE]; /* black key */
547 };
548
549 struct obd_capa {
550         struct hlist_node         c_hash;
551         struct list_head          c_list;
552
553         struct lustre_capa        c_capa;        /* capa */
554         int                       c_type;
555         atomic_t                  c_refc;
556
557         union {
558                 struct client_capa       client;
559                 struct filter_capa       filter;
560         } u;
561 };
562
563 #define c_inode    u.client.inode
564 #define c_handle   u.client.handle
565 #define c_lli_list u.client.lli_list
566 #define c_bvalid   u.filter.bvalid
567 #define c_bkeyid   u.filter.bkeyid
568 #define c_bhmac    u.filter.bhmac
569
570 enum lustre_capa_type {
571         CLIENT_CAPA = 0,
572         MDS_CAPA    = 1,
573         FILTER_CAPA = 2,
574 };
575
576 #define DEBUG_CAPA(level, capa, fmt, args...)                                  \
577 do {                                                                           \
578 CDEBUG(level, fmt " capa@%p uid %u/%u op %u ino "LPU64"/%u mdsid %d "          \
579        "keyid %d expiry "LPU64" flags %u\n",                                   \
580        ##args, capa, (capa)->lc_uid, (capa)->lc_ruid, (capa)->lc_op,           \
581        (capa)->lc_ino, (capa)->lc_igen, (capa)->lc_mdsid, (capa)->lc_keyid,    \
582        (capa)->lc_expiry, (capa)->lc_flags);                                   \
583 } while (0)
584
585 #define DEBUG_CAPA_KEY(level, key, fmt, args...)                               \
586 do {                                                                           \
587 CDEBUG(level, fmt " capa key@%p mdsid %d keyid %d expiry "LPU64"\n",           \
588        ##args, key, (key)->lk_mdsid, (key)->lk_keyid, (key)->lk_expiry);       \
589 } while (0)
590
591 #define DEBUG_MDS_CAPA_KEY(level, mkey, fmt, args...)                          \
592 do {                                                                           \
593 CDEBUG(level, fmt " capa key@%p mdsid %d keyid %d expiry "LPU64"\n",           \
594        ##args, mkey, le32_to_cpu((mkey)->k_key->lk_mdsid),                     \
595        le32_to_cpu((mkey)->k_key->lk_keyid),                                   \
596        le64_to_cpu((mkey)->k_key->lk_expiry));                                 \
597 } while (0)
598
599 extern spinlock_t capa_lock;
600 extern struct hlist_head *capa_hash;
601 extern struct list_head capa_list[];
602 extern struct timer_list ll_capa_timer;
603
604 /* obdclass/capa.c */
605 int capa_op(int flags);
606 void __capa_get(struct obd_capa *ocapa);
607 struct obd_capa *capa_get(uid_t uid, int capa_op, __u64 mdsid,
608                           unsigned long ino, __u32 igen, int type);
609 struct obd_capa *filter_capa_get(struct lustre_capa *capa);
610 void capa_put(struct obd_capa *ocapa);
611 struct obd_capa *capa_renew(struct lustre_capa *capa, int type);
612 void capa_hmac(struct crypto_tfm *tfm, __u8 *key, struct lustre_capa *capa);
613 void capa_dup(void *dst, struct obd_capa *ocapa);
614 void capa_dup2(void *dst, struct lustre_capa *capa);
615 int capa_expired(struct lustre_capa *capa);
616 int __capa_is_to_expire(struct obd_capa *ocapa, struct timeval *tv);
617 int capa_is_to_expire(struct obd_capa *ocapa);
618
619 #define CAPA_EXPIRY_SHIFT 10 /* 1024 sec */
620 #define CAPA_EXPIRY       (1UL << CAPA_EXPIRY_SHIFT)
621 #define CAPA_EXPIRY_MASK  (~(CAPA_EXPIRY-1))
622
623 #define CAPA_PRE_EXPIRY_SHORT   3       /* sec */
624 #define CAPA_PRE_EXPIRY         300     /* sec */
625
626 /* struct lustre_capa.lc_flags */
627 #define CAPA_FL_SHORT     0x001 /* short capa expiry */
628 #define CAPA_FL_REMUID    0x002 /* remote uid */
629
630 static inline unsigned long capa_pre_expiry(struct lustre_capa *capa)
631 {
632         return (capa->lc_flags & CAPA_FL_SHORT) ? 
633                         CAPA_PRE_EXPIRY_SHORT : CAPA_PRE_EXPIRY;
634 }
635
636 static inline __u64
637 round_expiry(__u32 timeout)
638 {
639         struct timeval tv;
640         int capa_expiry = CAPA_EXPIRY;
641         int mask = CAPA_EXPIRY_MASK;
642         __u64 expiry;
643
644         do_gettimeofday(&tv);
645         expiry = tv.tv_sec + timeout;
646
647         if (timeout < CAPA_EXPIRY) {
648                 capa_expiry = 64;
649                 mask = ~63;
650         }
651
652         expiry = (expiry + capa_expiry - 1) & mask;
653
654         return expiry;
655 }
656
657 static inline int
658 capa_key_cmp(struct lustre_capa_key *k1, struct lustre_capa_key *k2)
659 {
660         return k1->lk_keyid - k2->lk_keyid;
661 }
662
663 static inline unsigned long
664 expiry_to_jiffies(__u64 expiry)
665 {
666         /* sec -> jiffies */
667         struct timeval tv;
668         unsigned long timeout;
669
670         do_gettimeofday(&tv);
671         timeout = jiffies + ((unsigned long)expiry - tv.tv_sec) * HZ;
672         return timeout;
673 }
674
675 struct mds_capa_key {
676         struct list_head        k_list;
677
678         struct lustre_capa_key *k_key;
679         struct obd_device      *k_obd;
680 };
681
682 struct filter_capa_key {
683         struct list_head        k_list;
684         struct lustre_capa_key  k_key;
685 };
686
687 #endif /* __LINUX_SEC_H_ */