Whamcloud - gitweb
Land b_hd_capa onto HEAD (20050809_1942)
[fs/lustre-release.git] / lustre / include / linux / lustre_sec.h
index 94028b4..22bcffa 100644 (file)
 #ifndef __LINUX_SEC_H_
 #define __LINUX_SEC_H_
 
+//#include <linux/lustre_idl.h>
+
+enum ptlrpcs_major_flavors {
+        PTLRPCS_FLVR_MAJOR_NULL         = 0,
+        PTLRPCS_FLVR_MAJOR_GSS          = 1,
+        PTLRPCS_FLVR_MAJOR_MAX,
+};
+
+enum ptlrpcs_null_minor_flavors {
+        PTLRPCS_FLVR_MINOR_NULL         = 0,
+        PTLRPCS_FLVR_MINOR_NULL_MAX,
+};
+enum ptlrpcs_gss_minor_flavors {
+        PTLRPCS_FLVR_MINOR_GSS_NONE     = 0,
+        PTLRPCS_FLVR_MINOR_GSS_KRB5     = 1,
+        PTLRPCS_FLVR_MINOR_GSS_MAX,
+};
+
+enum ptlrpcs_security_type {
+        PTLRPCS_SVC_NONE                = 0,    /* no security */
+        PTLRPCS_SVC_AUTH                = 1,    /* authentication */
+        PTLRPCS_SVC_PRIV                = 2,    /* privacy */
+        PTLRPCS_SVC_MAX,
+};
+
+/*
+ * flavor compose/extract
+ */
+#define SEC_FLAVOR_MAJOR_OFFSET         (24)
+#define SEC_FLAVOR_RESERVE_OFFSET       (16)
+#define SEC_FLAVOR_SVC_OFFSET           (8)
+#define SEC_FLAVOR_MINOR_OFFSET         (0)
+
+#define SEC_MAKE_FLAVOR(major, minor, svc)                      \
+        (((__u32)(major) << SEC_FLAVOR_MAJOR_OFFSET) |          \
+         ((__u32)(svc) << SEC_FLAVOR_SVC_OFFSET) |              \
+         ((__u32)(minor) << SEC_FLAVOR_MINOR_OFFSET))
+
+#define SEC_MAKE_SUBFLAVOR(minor, svc)                          \
+        (((__u32)(svc) << SEC_FLAVOR_SVC_OFFSET) |              \
+         ((__u32)(minor) << SEC_FLAVOR_MINOR_OFFSET))
+
+#define SEC_FLAVOR_MAJOR(flavor)                                        \
+        ((((__u32)(flavor)) >> SEC_FLAVOR_MAJOR_OFFSET) & 0xFF)
+#define SEC_FLAVOR_MINOR(flavor)                                        \
+        ((((__u32)(flavor)) >> SEC_FLAVOR_MINOR_OFFSET) & 0xFF)
+#define SEC_FLAVOR_SVC(flavor)                                          \
+        ((((__u32)(flavor)) >> SEC_FLAVOR_SVC_OFFSET) & 0xFF)
+#define SEC_FLAVOR_SUB(flavor)                                          \
+        ((((__u32)(flavor)) >> SEC_FLAVOR_MINOR_OFFSET) & 0xFFFF)
+
+/*
+ * general gss flavors
+ */
+#define PTLRPCS_FLVR_GSS_NONE                           \
+        SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS,         \
+                        PTLRPCS_FLVR_MINOR_GSS_NONE,    \
+                        PTLRPCS_SVC_NONE)
+#define PTLRPCS_FLVR_GSS_AUTH                           \
+        SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS,         \
+                        PTLRPCS_FLVR_MINOR_GSS_NONE,    \
+                        PTLRPCS_SVC_AUTH)
+#define PTLRPCS_FLVR_GSS_PRIV                           \
+        SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS,         \
+                        PTLRPCS_FLVR_MINOR_GSS_NONE,    \
+                        PTLRPCS_SVC_PRIV)
+
+/*
+ * gss subflavors
+ */
+#define PTLRPCS_SUBFLVR_KRB5                            \
+        SEC_MAKE_SUBFLAVOR(PTLRPCS_FLVR_MINOR_GSS_KRB5, \
+                           PTLRPCS_SVC_NONE)
+#define PTLRPCS_SUBFLVR_KRB5I                           \
+        SEC_MAKE_SUBFLAVOR(PTLRPCS_FLVR_MINOR_GSS_KRB5, \
+                           PTLRPCS_SVC_AUTH)
+#define PTLRPCS_SUBFLVR_KRB5P                           \
+        SEC_MAKE_SUBFLAVOR(PTLRPCS_FLVR_MINOR_GSS_KRB5, \
+                           PTLRPCS_SVC_PRIV)
+
+/*
+ * "end user" flavors
+ */
+#define PTLRPCS_FLVR_NULL                               \
+        SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_NULL,        \
+                        PTLRPCS_FLVR_MINOR_NULL,        \
+                        PTLRPCS_SVC_NONE)
+#define PTLRPCS_FLVR_KRB5                               \
+        SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS,         \
+                        PTLRPCS_FLVR_MINOR_GSS_KRB5,    \
+                        PTLRPCS_SVC_NONE)
+#define PTLRPCS_FLVR_KRB5I                              \
+        SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS,         \
+                        PTLRPCS_FLVR_MINOR_GSS_KRB5,    \
+                        PTLRPCS_SVC_AUTH)
+#define PTLRPCS_FLVR_KRB5P                              \
+        SEC_MAKE_FLAVOR(PTLRPCS_FLVR_MAJOR_GSS,         \
+                        PTLRPCS_FLVR_MINOR_GSS_KRB5,    \
+                        PTLRPCS_SVC_PRIV)
+
+#define PTLRPCS_FLVR_INVALID    (-1)
+
+__u32 ptlrpcs_name2flavor(const char *name);
+char *ptlrpcs_flavor2name(__u32 flavor);
+
+
+#ifdef __KERNEL__
+
 /* forward declaration */
 struct obd_import;
 struct ptlrpc_request;
@@ -30,25 +138,18 @@ struct ptlrpc_credops;
 struct ptlrpc_sec;
 struct ptlrpc_secops;
 
-#define PTLRPC_SEC_MAX_FLAVORS   (4)
-
-typedef struct ptlrpcs_flavor_s {
-        __u32   flavor;
-        __u32   subflavor;
-} ptlrpcs_flavor_t;
 
-enum ptlrpcs_security_type {
-        PTLRPC_SEC_TYPE_NONE    = 0,    /* no security */
-        PTLRPC_SEC_TYPE_AUTH    = 1,    /* authentication */
-        PTLRPC_SEC_TYPE_PRIV    = 2,    /* privacy */
-};
+typedef struct {
+        struct list_head        list;
+        __u32                   flavor;
+} deny_sec_t;
 
 /*
  * This header is prepended at any on-wire ptlrpc packets
  */
 struct ptlrpcs_wire_hdr {
         __u32   flavor;
-        __u32   sectype;
+        __u32   unused;
         __u32   msg_len;
         __u32   sec_len;
 };
@@ -73,50 +174,39 @@ __u8 *buf_to_sec_data(void *buf)
         return (__u8 *) (buf + sizeof(*hdr) + hdr->msg_len);
 }
 
-enum ptlrpcs_flavors {
-        PTLRPC_SEC_NULL = 0,
-        PTLRPC_SEC_GSS  = 1,
-};
-
 #define PTLRPC_SEC_GSS_VERSION (1)
 
-enum ptlrpcs_gss_subflavors {
-        PTLRPC_SEC_GSS_KRB5  = 0,
-        PTLRPC_SEC_GSS_KRB5I = 1,
-        PTLRPC_SEC_GSS_KRB5P = 2,
-};
-
 enum ptlrpcs_gss_proc {
-        PTLRPC_GSS_PROC_DATA =          0,
-        PTLRPC_GSS_PROC_INIT =          1,
-        PTLRPC_GSS_PROC_CONTINUE_INIT = 2,
-        PTLRPC_GSS_PROC_DESTROY =       3,
-        PTLRPC_GSS_PROC_ERR =           4,
+        PTLRPCS_GSS_PROC_DATA           = 0,
+        PTLRPCS_GSS_PROC_INIT           = 1,
+        PTLRPCS_GSS_PROC_CONTINUE_INIT  = 2,
+        PTLRPCS_GSS_PROC_DESTROY        = 3,
+        PTLRPCS_GSS_PROC_ERR            = 4,
 };
                                                                                                                         
 enum ptlrpcs_gss_svc {
-        PTLRPC_GSS_SVC_NONE =           1,
-        PTLRPC_GSS_SVC_INTEGRITY =      2,
-        PTLRPC_GSS_SVC_PRIVACY =        3,
+        PTLRPCS_GSS_SVC_NONE            = 1,
+        PTLRPCS_GSS_SVC_INTEGRITY       = 2,
+        PTLRPCS_GSS_SVC_PRIVACY         = 3,
 };
 
 enum ptlrpcs_error {
-        PTLRPCS_OK =                    0,
-        PTLRPCS_BADCRED =               1,
-        PTLRPCS_REJECTEDCRED =          2,
-        PTLRPCS_BADVERF =               3,
-        PTLRPCS_REJECTEDVERF =          4,
-        PTLRPCS_TOOWEAK =               5,
+        PTLRPCS_OK                      = 0,
+        PTLRPCS_BADCRED                 = 1,
+        PTLRPCS_REJECTEDCRED            = 2,
+        PTLRPCS_BADVERF                 = 3,
+        PTLRPCS_REJECTEDVERF            = 4,
+        PTLRPCS_TOOWEAK                 = 5,
         /* GSS errors */
-        PTLRPCS_GSS_CREDPROBLEM =       13,
-        PTLRPCS_GSS_CTXPROBLEM =        14,
+        PTLRPCS_GSS_CREDPROBLEM         = 13,
+        PTLRPCS_GSS_CTXPROBLEM          = 14,
 };
 
 struct vfs_cred {
-        __u64   vc_pag;
-        uid_t   vc_uid;
-        gid_t   vc_gid;
-        struct group_info *vc_ginfo;
+        __u64                   vc_pag;
+        uid_t                   vc_uid;
+        gid_t                   vc_gid;
+        struct group_info      *vc_ginfo;
 };
 
 struct ptlrpc_credops {
@@ -133,10 +223,17 @@ struct ptlrpc_credops {
                            struct ptlrpc_request *req);
 };
 
-#define PTLRPC_CRED_UPTODATE    0x00000001 /* uptodate */
-#define PTLRPC_CRED_DEAD        0x00000002 /* mark expired gracefully */
-#define PTLRPC_CRED_ERROR       0x00000004 /* fatal error (refresh, etc.) */
-#define PTLRPC_CRED_FLAGS_MASK  0x00000007
+#define PTLRPC_CRED_UPTODATE_BIT        0 /* uptodate */
+#define PTLRPC_CRED_DEAD_BIT            1 /* mark expired gracefully */
+#define PTLRPC_CRED_ERROR_BIT           2 /* fatal error (refresh, etc.) */
+
+#define PTLRPC_CRED_UPTODATE            (1 << PTLRPC_CRED_UPTODATE_BIT)
+#define PTLRPC_CRED_DEAD                (1 << PTLRPC_CRED_DEAD_BIT)
+#define PTLRPC_CRED_ERROR               (1 << PTLRPC_CRED_ERROR_BIT)
+
+#define PTLRPC_CRED_FLAGS_MASK          (PTLRPC_CRED_UPTODATE |         \
+                                         PTLRPC_CRED_DEAD |             \
+                                         PTLRPC_CRED_ERROR)
 
 struct ptlrpc_cred {
         struct list_head        pc_hash;   /* linked into hash table */
@@ -144,14 +241,14 @@ struct ptlrpc_cred {
         struct ptlrpc_sec      *pc_sec;
         struct ptlrpc_credops  *pc_ops;
         unsigned long           pc_expire;
-        int                     pc_flags;
+        unsigned long           pc_flags;
         /* XXX maybe should not be here */
         __u64                   pc_pag;
         uid_t                   pc_uid;
 };
 
 struct ptlrpc_secops {
-        struct ptlrpc_sec *   (*create_sec)    (ptlrpcs_flavor_t *flavor,
+        struct ptlrpc_sec *   (*create_sec)    (__u32 flavor,
                                                 const char *pipe_dir,
                                                 void *pipe_data);
         void                  (*destroy_sec)   (struct ptlrpc_sec *sec);
@@ -170,8 +267,10 @@ struct ptlrpc_secops {
                                                 struct ptlrpc_request *req);
         /* security payload size estimation */
         int                   (*est_req_payload)(struct ptlrpc_sec *sec,
+                                                 struct ptlrpc_request *req,
                                                  int msgsize);
         int                   (*est_rep_payload)(struct ptlrpc_sec *sec,
+                                                 struct ptlrpc_request *req,
                                                  int msgsize);
 };
 
@@ -179,10 +278,14 @@ struct ptlrpc_sec_type {
         struct module          *pst_owner;
         char                   *pst_name;
         atomic_t                pst_inst;       /* instance, debug only */
-        ptlrpcs_flavor_t        pst_flavor;
+        __u32                   pst_flavor;     /* major flavor */
         struct ptlrpc_secops   *pst_ops;
 };
 
+#define PTLRPC_SEC_FL_MDS               0x0001 /* outgoing from MDS */
+#define PTLRPC_SEC_FL_REVERSE           0x0002 /* reverse sec */
+#define PTLRPC_SEC_FL_PAG               0x0004 /* enable PAG */
+
 #define PTLRPC_CREDCACHE_NR     8
 #define PTLRPC_CREDCACHE_MASK   (PTLRPC_CREDCACHE_NR - 1)
 
@@ -190,22 +293,22 @@ struct ptlrpc_sec {
         struct ptlrpc_sec_type *ps_type;
         struct list_head        ps_credcache[PTLRPC_CREDCACHE_NR];
         spinlock_t              ps_lock;        /* protect cred cache */
-        __u32                   ps_sectype;
-        ptlrpcs_flavor_t        ps_flavor;
+        __u32                   ps_flavor;
         atomic_t                ps_refcount;
         atomic_t                ps_credcount;
         struct obd_import      *ps_import;
         /* actual security model need initialize following fields */
         unsigned long           ps_expire;      /* cache expire interval */
         unsigned long           ps_nextgc;      /* next gc time */
-        unsigned int            ps_flags;
+        unsigned long           ps_flags;
 };
 
 /* sec.c */
 int  ptlrpcs_register(struct ptlrpc_sec_type *type);
 int  ptlrpcs_unregister(struct ptlrpc_sec_type *type);
 
-struct ptlrpc_sec * ptlrpcs_sec_create(ptlrpcs_flavor_t *flavor,
+struct ptlrpc_sec * ptlrpcs_sec_create(__u32 flavor,
+                                       unsigned long flags,
                                        struct obd_import *import,
                                        const char *pipe_dir,
                                        void *pipe_data);
@@ -222,13 +325,6 @@ static inline void ptlrpcs_cred_get(struct ptlrpc_cred *cred)
         atomic_inc(&cred->pc_refcount);
 }
 
-static inline int ptlrpcs_cred_is_uptodate(struct ptlrpc_cred *cred)
-{
-        LASSERT(cred);
-        LASSERT(atomic_read(&cred->pc_refcount));
-        return ((cred->pc_flags & PTLRPC_CRED_FLAGS_MASK) ==
-                PTLRPC_CRED_UPTODATE);
-}
 static inline int ptlrpcs_cred_refresh(struct ptlrpc_cred *cred)
 {
         LASSERT(cred);
@@ -237,26 +333,45 @@ static inline int ptlrpcs_cred_refresh(struct ptlrpc_cred *cred)
         LASSERT(cred->pc_ops->refresh);
         return cred->pc_ops->refresh(cred);
 }
-static inline void ptlrpcs_cred_die(struct ptlrpc_cred *cred)
+
+static inline int ptlrpcs_cred_is_uptodate(struct ptlrpc_cred *cred)
 {
-        LASSERT(atomic_read(&cred->pc_refcount));
-        LASSERT(cred->pc_sec);
-        if (!(cred->pc_flags & PTLRPC_CRED_DEAD)) {
-                spin_lock(&cred->pc_sec->ps_lock);
-                cred->pc_flags |= PTLRPC_CRED_DEAD;
-                cred->pc_flags &= ~PTLRPC_CRED_UPTODATE;
-                list_del_init(&cred->pc_hash);
-                spin_unlock(&cred->pc_sec->ps_lock);
-        }
+        smp_mb();
+        return ((cred->pc_flags & PTLRPC_CRED_FLAGS_MASK) ==
+                PTLRPC_CRED_UPTODATE);
 }
+
 static inline int ptlrpcs_cred_is_dead(struct ptlrpc_cred *cred)
 {
-        return(cred->pc_flags & PTLRPC_CRED_DEAD);
+        smp_mb();
+        return ((cred->pc_flags & (PTLRPC_CRED_DEAD | PTLRPC_CRED_ERROR)) != 0);
 }
 
-static inline int ptlrpcs_est_req_payload(struct ptlrpc_sec *sec,
+#define ptlrpcs_cred_expire(cred)                                       \
+        if (!test_and_set_bit(PTLRPC_CRED_DEAD_BIT, &cred->pc_flags)) { \
+                CWARN("cred %p: get expired\n", cred);                  \
+                clear_bit(PTLRPC_CRED_UPTODATE_BIT, &cred->pc_flags);   \
+        }
+
+static inline int ptlrpcs_cred_check_uptodate(struct ptlrpc_cred *cred)
+{
+        LASSERT(atomic_read(&cred->pc_refcount));
+
+        if (!ptlrpcs_cred_is_uptodate(cred))
+                return 1;
+
+        if (cred->pc_expire == 0)
+                return 0;
+        if (time_after(cred->pc_expire, get_seconds()))
+                return 0;
+        ptlrpcs_cred_expire(cred);
+        return 1;
+}
+
+static inline int ptlrpcs_est_req_payload(struct ptlrpc_request *req,
                                           int datasize)
 {
+        struct ptlrpc_sec *sec = req->rq_cred->pc_sec;
         struct ptlrpc_secops *ops;
 
         LASSERT(sec);
@@ -265,14 +380,15 @@ static inline int ptlrpcs_est_req_payload(struct ptlrpc_sec *sec,
 
         ops = sec->ps_type->pst_ops;
         if (ops->est_req_payload)
-                return ops->est_req_payload(sec, datasize);
+                return ops->est_req_payload(sec, req, datasize);
         else
                 return 0;
 }
 
-static inline int ptlrpcs_est_rep_payload(struct ptlrpc_sec *sec,
+static inline int ptlrpcs_est_rep_payload(struct ptlrpc_request *req,
                                           int datasize)
 {
+        struct ptlrpc_sec *sec = req->rq_cred->pc_sec;
         struct ptlrpc_secops *ops;
 
         LASSERT(sec);
@@ -281,11 +397,38 @@ static inline int ptlrpcs_est_rep_payload(struct ptlrpc_sec *sec,
 
         ops = sec->ps_type->pst_ops;
         if (ops->est_rep_payload)
-                return ops->est_rep_payload(sec, datasize);
+                return ops->est_rep_payload(sec, req, datasize);
         else
                 return 0;
 }
 
+static inline int add_deny_security(char *sec, struct list_head *head)
+{
+        deny_sec_t     *p_deny_sec = NULL;
+        int             rc = 0;
+
+        LASSERT(sec != NULL);
+
+        OBD_ALLOC(p_deny_sec, sizeof(*p_deny_sec));
+        if (p_deny_sec == NULL)
+                return -ENOMEM;
+
+        p_deny_sec->flavor = ptlrpcs_name2flavor(sec);
+        if (p_deny_sec->flavor == PTLRPCS_FLVR_INVALID) {
+                CERROR("unrecognized security type %s\n", (char*) sec);
+                rc = -EINVAL;
+                goto out;
+        }
+
+        list_add_tail(&p_deny_sec->list, head);
+out:
+        if (rc) {
+                if (p_deny_sec)
+                        OBD_FREE(p_deny_sec, sizeof(*p_deny_sec));
+        }
+        return rc;
+}
+
 int ptlrpcs_cli_wrap_request(struct ptlrpc_request *req);
 int ptlrpcs_cli_unwrap_reply(struct ptlrpc_request *req);
 int ptlrpcs_cli_alloc_reqbuf(struct ptlrpc_request *req, int msgsize);
@@ -296,10 +439,12 @@ void ptlrpcs_cli_free_repbuf(struct ptlrpc_request *req);
 /* higher interface */
 int  ptlrpcs_import_get_sec(struct obd_import *imp);
 void ptlrpcs_import_drop_sec(struct obd_import *imp);
+void ptlrpcs_import_flush_current_creds(struct obd_import *imp);
 int  ptlrpcs_req_get_cred(struct ptlrpc_request *req);
 void ptlrpcs_req_drop_cred(struct ptlrpc_request *req);
 int  ptlrpcs_req_replace_dead_cred(struct ptlrpc_request *req);
 int  ptlrpcs_req_refresh_cred(struct ptlrpc_request *req);
+int ptlrpcs_check_cred(struct obd_import *imp);
 
 /* internal helpers */
 int sec_alloc_reqbuf(struct ptlrpc_sec *sec, struct ptlrpc_request *req,
@@ -319,7 +464,7 @@ struct ptlrpc_reply_state;
 struct ptlrpc_svcsec {
         struct module           *pss_owner;
         char                    *pss_name;
-        ptlrpcs_flavor_t         pss_flavor;
+        __u32                    pss_flavor;    /* major flavor */
         int                      pss_sec_size;
 
         int                    (*accept)      (struct ptlrpc_request *req,
@@ -360,4 +505,146 @@ void svcsec_free_reply_state(struct ptlrpc_reply_state *rs);
 int svcsec_null_init(void);
 int svcsec_null_exit(void);
 
+/* capability */
+#include <linux/crypto.h>
+
+#define NR_CAPAHASH 32
+#define CAPA_TIMEOUT 1800                /* sec, == 30 min */
+#define CAPA_KEY_TIMEOUT (24 * 60 * 60)  /* sec, == 1 day */
+#define CAPA_CACHE_SIZE 1000             /* for MDS & OST */
+#define CAPA_HMAC_ALG "sha1"
+
+struct lustre_capa_data {
+        __u32   lc_uid;       /* uid */
+        __u32   lc_op;        /* operations allowed */
+        __u64   lc_ino;       /* inode# */
+        __u32   lc_mdsid;     /* mds# */
+        __u32   lc_keyid;     /* key used for the capability */
+        __u64   lc_expiry;    /* expiry time: servers have clocks */
+        __u32   lc_flags;     /* security features for capability */
+} __attribute__((packed));
+
+struct client_capa {
+        struct inode             *inode;      /* this should be always valid
+                                               * if c_refc > 0 */
+        struct lustre_handle      handle;     /* handle of mds_file_data */
+        struct list_head         *list;       /* the capa list belong to this client */
+        struct timer_list        *timer;      /* timer belong to this client */
+};
+
+struct filter_capa {
+        int                       bvalid;     /* black key here valid or not */
+        __u32                     bkeyid;     /* black key id */
+        __u8                      bhmac[CAPA_DIGEST_SIZE]; /* black key */
+};
+
+struct obd_capa {
+        struct hlist_node         c_hash;
+        struct list_head          c_list;
+
+        struct lustre_capa        c_capa;        /* capa */
+        int                       c_type;
+        atomic_t                  c_refc;
+
+        union {
+                struct client_capa       client;
+                struct filter_capa       filter;
+        } u;
+};
+
+#define c_inode   u.client.inode
+#define c_handle  u.client.handle
+#define c_bvalid  u.filter.bvalid
+#define c_bkeyid  u.filter.bkeyid
+#define c_bhmac   u.filter.bhmac
+
+enum lustre_capa_type {
+        CLIENT_CAPA = 0,
+        MDS_CAPA    = 1,
+        FILTER_CAPA = 2,
+};
+
+extern spinlock_t capa_lock;
+extern struct hlist_head *capa_hash;
+extern struct list_head capa_list[];
+extern struct timer_list ll_capa_timer;
+
+/* obdclass/capa.c */
+int capa_op(int flags);
+void __capa_get(struct obd_capa *ocapa);
+struct obd_capa *capa_get(uid_t uid, int capa_op, __u64 mdsid,
+                          unsigned long ino, int type,
+                          struct lustre_capa *capa, struct inode *inode,
+                          struct lustre_handle *handle);
+void capa_put(struct obd_capa *ocapa, int type);
+int capa_renew(struct lustre_capa *capa, int type);
+void capa_hmac(struct crypto_tfm *tfm, u8 *key, struct lustre_capa *capa);
+void capa_dup(void *dst, struct obd_capa *ocapa);
+void capa_dup2(void *dst, struct lustre_capa *capa);
+int capa_expired(struct lustre_capa *capa);
+int __capa_is_to_expire(struct obd_capa *ocapa);
+int capa_is_to_expire(struct obd_capa *ocapa);
+
+#define CAPA_EXPIRY_SHIFT 10 /* 1024 sec */
+#define CAPA_EXPIRY       (1UL << PAGE_SHIFT)
+#define CAPA_EXPIRY_MASK  (~(CAPA_EXPIRY-1))
+
+#define CAPA_PRE_EXPIRY_NOROUND 3       /* sec */
+#define CAPA_PRE_EXPIRY         300     /* sec */
+
+/* struct lustre_capa.lc_flags */
+#define CAPA_FL_NOROUND   0x001 /* capa expiry not rounded */
+
+static inline unsigned long capa_pre_expiry(struct lustre_capa *capa)
+{
+        return (capa->lc_flags & CAPA_FL_NOROUND) ? 
+                        CAPA_PRE_EXPIRY_NOROUND : CAPA_PRE_EXPIRY;
+}
+
+static inline __u64
+round_expiry(__u32 timeout)
+{
+        struct timeval tv;
+        __u64 expiry;
+
+        do_gettimeofday(&tv);
+        expiry = tv.tv_sec + timeout;
+
+        if (timeout > CAPA_EXPIRY)
+                expiry = (expiry + CAPA_EXPIRY - 1) & CAPA_EXPIRY_MASK;
+
+        return expiry;
+}
+
+static inline int
+capa_key_cmp(struct lustre_capa_key *k1, struct lustre_capa_key *k2)
+{
+        return le32_to_cpu(k1->lk_keyid) - le32_to_cpu(k2->lk_keyid);
+}
+
+static inline unsigned long
+expiry_to_jiffies(__u64 expiry)
+{
+        /* sec -> jiffies */
+        struct timeval tv;
+
+        do_gettimeofday(&tv);
+        return jiffies + ((unsigned long)expiry - tv.tv_sec) * HZ;
+}
+
+#endif /* __KERNEL__ */
+
+struct mds_capa_key {
+        struct list_head        k_list;
+
+        struct lustre_capa_key *k_key;
+        struct obd_device      *k_obd;
+};
+
+struct filter_capa_key {
+        struct list_head        k_list;
+
+        struct lustre_capa_key  k_key;
+};
+
 #endif /* __LINUX_SEC_H_ */