block: use normal I/O path for discard requests
[safe/jmp/linux-2.6] / include / linux / key.h
index 2c24ffa..cd50dfa 100644 (file)
@@ -1,6 +1,6 @@
-/* key.h: authentication token and access key management
+/* Authentication token and access key management
  *
- * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2004, 2007 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
  *
  * This program is free software; you can redistribute it and/or
@@ -19,6 +19,8 @@
 #include <linux/list.h>
 #include <linux/rbtree.h>
 #include <linux/rcupdate.h>
+#include <linux/sysctl.h>
+#include <linux/rwsem.h>
 #include <asm/atomic.h>
 
 #ifdef __KERNEL__
@@ -35,30 +37,44 @@ struct key;
 
 #undef KEY_DEBUGGING
 
-#define KEY_USR_VIEW   0x00010000      /* user can view a key's attributes */
-#define KEY_USR_READ   0x00020000      /* user can read key payload / view keyring */
-#define KEY_USR_WRITE  0x00040000      /* user can update key payload / add link to keyring */
-#define KEY_USR_SEARCH 0x00080000      /* user can find a key in search / search a keyring */
-#define KEY_USR_LINK   0x00100000      /* user can create a link to a key/keyring */
-#define KEY_USR_ALL    0x001f0000
+#define KEY_POS_VIEW   0x01000000      /* possessor can view a key's attributes */
+#define KEY_POS_READ   0x02000000      /* possessor can read key payload / view keyring */
+#define KEY_POS_WRITE  0x04000000      /* possessor can update key payload / add link to keyring */
+#define KEY_POS_SEARCH 0x08000000      /* possessor can find a key in search / search a keyring */
+#define KEY_POS_LINK   0x10000000      /* possessor can create a link to a key/keyring */
+#define KEY_POS_SETATTR        0x20000000      /* possessor can set key attributes */
+#define KEY_POS_ALL    0x3f000000
+
+#define KEY_USR_VIEW   0x00010000      /* user permissions... */
+#define KEY_USR_READ   0x00020000
+#define KEY_USR_WRITE  0x00040000
+#define KEY_USR_SEARCH 0x00080000
+#define KEY_USR_LINK   0x00100000
+#define KEY_USR_SETATTR        0x00200000
+#define KEY_USR_ALL    0x003f0000
 
 #define KEY_GRP_VIEW   0x00000100      /* group permissions... */
 #define KEY_GRP_READ   0x00000200
 #define KEY_GRP_WRITE  0x00000400
 #define KEY_GRP_SEARCH 0x00000800
 #define KEY_GRP_LINK   0x00001000
-#define KEY_GRP_ALL    0x00001f00
+#define KEY_GRP_SETATTR        0x00002000
+#define KEY_GRP_ALL    0x00003f00
 
 #define KEY_OTH_VIEW   0x00000001      /* third party permissions... */
 #define KEY_OTH_READ   0x00000002
 #define KEY_OTH_WRITE  0x00000004
 #define KEY_OTH_SEARCH 0x00000008
 #define KEY_OTH_LINK   0x00000010
-#define KEY_OTH_ALL    0x0000001f
+#define KEY_OTH_SETATTR        0x00000020
+#define KEY_OTH_ALL    0x0000003f
+
+#define KEY_PERM_UNDEF 0xffffffff
 
 struct seq_file;
 struct user_struct;
 struct signal_struct;
+struct cred;
 
 struct key_type;
 struct key_owner;
@@ -67,6 +83,38 @@ struct keyring_name;
 
 /*****************************************************************************/
 /*
+ * key reference with possession attribute handling
+ *
+ * NOTE! key_ref_t is a typedef'd pointer to a type that is not actually
+ * defined. This is because we abuse the bottom bit of the reference to carry a
+ * flag to indicate whether the calling process possesses that key in one of
+ * its keyrings.
+ *
+ * the key_ref_t has been made a separate type so that the compiler can reject
+ * attempts to dereference it without proper conversion.
+ *
+ * the three functions are used to assemble and disassemble references
+ */
+typedef struct __key_reference_with_attributes *key_ref_t;
+
+static inline key_ref_t make_key_ref(const struct key *key,
+                                    unsigned long possession)
+{
+       return (key_ref_t) ((unsigned long) key | possession);
+}
+
+static inline struct key *key_ref_to_ptr(const key_ref_t key_ref)
+{
+       return (struct key *) ((unsigned long) key_ref & ~1UL);
+}
+
+static inline unsigned long is_key_possessed(const key_ref_t key_ref)
+{
+       return (unsigned long) key_ref & 1UL;
+}
+
+/*****************************************************************************/
+/*
  * authentication token / access credential / keyring
  * - types of key include:
  *   - keyrings
@@ -80,7 +128,11 @@ struct key {
        struct key_type         *type;          /* type of key */
        struct rw_semaphore     sem;            /* change vs change sem */
        struct key_user         *user;          /* owner of this key */
-       time_t                  expiry;         /* time at which key expires (or 0) */
+       void                    *security;      /* security data for this key */
+       union {
+               time_t          expiry;         /* time at which key expires (or 0) */
+               time_t          revoked_at;     /* time at which key was revoked */
+       };
        uid_t                   uid;
        gid_t                   gid;
        key_perm_t              perm;           /* access permissions */
@@ -116,6 +168,8 @@ struct key {
         */
        union {
                struct list_head        link;
+               unsigned long           x[2];
+               void                    *p[2];
        } type_data;
 
        /* key data
@@ -129,80 +183,18 @@ struct key {
        } payload;
 };
 
-/*****************************************************************************/
-/*
- * kernel managed key type definition
- */
-struct key_type {
-       /* name of the type */
-       const char *name;
-
-       /* default payload length for quota precalculation (optional)
-        * - this can be used instead of calling key_payload_reserve(), that
-        *   function only needs to be called if the real datalen is different
-        */
-       size_t def_datalen;
-
-       /* instantiate a key of this type
-        * - this method should call key_payload_reserve() to determine if the
-        *   user's quota will hold the payload
-        */
-       int (*instantiate)(struct key *key, const void *data, size_t datalen);
-
-       /* duplicate a key of this type (optional)
-        * - the source key will be locked against change
-        * - the new description will be attached
-        * - the quota will have been adjusted automatically from
-        *   source->quotalen
-        */
-       int (*duplicate)(struct key *key, const struct key *source);
-
-       /* update a key of this type (optional)
-        * - this method should call key_payload_reserve() to recalculate the
-        *   quota consumption
-        * - the key must be locked against read when modifying
-        */
-       int (*update)(struct key *key, const void *data, size_t datalen);
-
-       /* match a key against a description */
-       int (*match)(const struct key *key, const void *desc);
-
-       /* clear the data from a key (optional) */
-       void (*destroy)(struct key *key);
-
-       /* describe a key */
-       void (*describe)(const struct key *key, struct seq_file *p);
-
-       /* read a key's data (optional)
-        * - permission checks will be done by the caller
-        * - the key's semaphore will be readlocked by the caller
-        * - should return the amount of data that could be read, no matter how
-        *   much is copied into the buffer
-        * - shouldn't do the copy if the buffer is NULL
-        */
-       long (*read)(const struct key *key, char __user *buffer, size_t buflen);
-
-       /* internal fields */
-       struct list_head        link;           /* link in types list */
-};
+extern struct key *key_alloc(struct key_type *type,
+                            const char *desc,
+                            uid_t uid, gid_t gid,
+                            const struct cred *cred,
+                            key_perm_t perm,
+                            unsigned long flags);
 
-extern struct key_type key_type_keyring;
 
-extern int register_key_type(struct key_type *ktype);
-extern void unregister_key_type(struct key_type *ktype);
+#define KEY_ALLOC_IN_QUOTA     0x0000  /* add to quota, reject if would overrun */
+#define KEY_ALLOC_QUOTA_OVERRUN        0x0001  /* add to quota, permit even if overrun */
+#define KEY_ALLOC_NOT_IN_QUOTA 0x0002  /* not in quota */
 
-extern struct key *key_alloc(struct key_type *type,
-                            const char *desc,
-                            uid_t uid, gid_t gid, key_perm_t perm,
-                            int not_in_quota);
-extern int key_payload_reserve(struct key *key, size_t datalen);
-extern int key_instantiate_and_link(struct key *key,
-                                   const void *data,
-                                   size_t datalen,
-                                   struct key *keyring);
-extern int key_negate_and_link(struct key *key,
-                              unsigned timeout,
-                              struct key *keyring);
 extern void key_revoke(struct key *key);
 extern void key_put(struct key *key);
 
@@ -213,20 +205,45 @@ static inline struct key *key_get(struct key *key)
        return key;
 }
 
+static inline void key_ref_put(key_ref_t key_ref)
+{
+       key_put(key_ref_to_ptr(key_ref));
+}
+
 extern struct key *request_key(struct key_type *type,
                               const char *description,
                               const char *callout_info);
 
+extern struct key *request_key_with_auxdata(struct key_type *type,
+                                           const char *description,
+                                           const void *callout_info,
+                                           size_t callout_len,
+                                           void *aux);
+
+extern struct key *request_key_async(struct key_type *type,
+                                    const char *description,
+                                    const void *callout_info,
+                                    size_t callout_len);
+
+extern struct key *request_key_async_with_auxdata(struct key_type *type,
+                                                 const char *description,
+                                                 const void *callout_info,
+                                                 size_t callout_len,
+                                                 void *aux);
+
+extern int wait_for_key_construction(struct key *key, bool intr);
+
 extern int key_validate(struct key *key);
 
-extern struct key *key_create_or_update(struct key *keyring,
-                                       const char *type,
-                                       const char *description,
-                                       const void *payload,
-                                       size_t plen,
-                                       int not_in_quota);
+extern key_ref_t key_create_or_update(key_ref_t keyring,
+                                     const char *type,
+                                     const char *description,
+                                     const void *payload,
+                                     size_t plen,
+                                     key_perm_t perm,
+                                     unsigned long flags);
 
-extern int key_update(struct key *key,
+extern int key_update(key_ref_t key,
                      const void *payload,
                      size_t plen);
 
@@ -237,38 +254,36 @@ extern int key_unlink(struct key *keyring,
                      struct key *key);
 
 extern struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
-                                int not_in_quota, struct key *dest);
+                                const struct cred *cred,
+                                unsigned long flags,
+                                struct key *dest);
 
 extern int keyring_clear(struct key *keyring);
 
-extern struct key *keyring_search(struct key *keyring,
-                                 struct key_type *type,
-                                 const char *description);
-
-extern struct key *search_process_keyrings(struct key_type *type,
-                                          const char *description);
+extern key_ref_t keyring_search(key_ref_t keyring,
+                               struct key_type *type,
+                               const char *description);
 
 extern int keyring_add_key(struct key *keyring,
                           struct key *key);
 
 extern struct key *key_lookup(key_serial_t id);
 
-extern void keyring_replace_payload(struct key *key, void *replacement);
+static inline key_serial_t key_serial(struct key *key)
+{
+       return key ? key->serial : 0;
+}
+
+#ifdef CONFIG_SYSCTL
+extern ctl_table key_sysctls[];
+#endif
 
-#define key_serial(key) ((key) ? (key)->serial : 0)
+extern void key_replace_session_keyring(void);
 
 /*
  * the userspace interface
  */
-extern struct key root_user_keyring, root_session_keyring;
-extern int alloc_uid_keyring(struct user_struct *user);
-extern void switch_uid_keyring(struct user_struct *new_user);
-extern int copy_keys(unsigned long clone_flags, struct task_struct *tsk);
-extern int copy_thread_group_keys(struct task_struct *tsk);
-extern void exit_keys(struct task_struct *tsk);
-extern void exit_thread_group_keys(struct signal_struct *tg);
-extern int suid_keys(struct task_struct *tsk);
-extern int exec_keys(struct task_struct *tsk);
+extern int install_thread_keyring_to_cred(struct cred *cred);
 extern void key_fsuid_changed(struct task_struct *tsk);
 extern void key_fsgid_changed(struct task_struct *tsk);
 extern void key_init(void);
@@ -277,19 +292,17 @@ extern void key_init(void);
 
 #define key_validate(k)                        0
 #define key_serial(k)                  0
-#define key_get(k)                     NULL
+#define key_get(k)                     ({ NULL; })
+#define key_revoke(k)                  do { } while(0)
 #define key_put(k)                     do { } while(0)
-#define alloc_uid_keyring(u)           0
-#define switch_uid_keyring(u)          do { } while(0)
-#define copy_keys(f,t)                 0
-#define copy_thread_group_keys(t)      0
-#define exit_keys(t)                   do { } while(0)
-#define exit_thread_group_keys(tg)     do { } while(0)
-#define suid_keys(t)                   do { } while(0)
-#define exec_keys(t)                   do { } while(0)
+#define key_ref_put(k)                 do { } while(0)
+#define make_key_ref(k, p)             NULL
+#define key_ref_to_ptr(k)              NULL
+#define is_key_possessed(k)            0
 #define key_fsuid_changed(t)           do { } while(0)
 #define key_fsgid_changed(t)           do { } while(0)
 #define key_init()                     do { } while(0)
+#define key_replace_session_keyring()  do { } while(0)
 
 #endif /* CONFIG_KEYS */
 #endif /* __KERNEL__ */