/**************************************/
/* Rule Set Based Access Control      */
/* Author and (c) 1999,2000: Amon Ott */
/* Data structures / ACL              */
/* Last modified: 14/Apr/2000         */
/**************************************/

#ifndef __RSBAC_ACL_DATA_STRUC_H
#define __RSBAC_ACL_DATA_STRUC_H

#include <linux/types.h>
#include <rsbac/aci.h>
#include <rsbac/types.h>

#define RSBAC_ACL_GENERAL_FD_ENTRY \
   { ACLS_GROUP, \
     RSBAC_ACL_GROUP_EVERYONE, \
     ( RSBAC_FD_REQUEST_VECTOR & RSBAC_READ_WRITE_REQUEST_VECTOR ) | RSBAC_ACL_GEN_RIGHTS_VECTOR }

#define RSBAC_ACL_ACMAN_FD_ENTRY \
   { ACLS_USER, \
     RSBAC_SECOFF_UID, \
     ( RSBAC_FD_REQUEST_VECTOR & \
       ( RSBAC_READ_WRITE_REQUEST_VECTOR | RSBAC_SECURITY_REQUEST_VECTOR ) ) \
     | RSBAC_ACL_ACMAN_RIGHTS_VECTOR }

#define RSBAC_ACL_SYSADM_FD_ENTRY \
   { ACLS_USER, \
     RSBAC_SYSADM_UID, \
     ( RSBAC_FD_REQUEST_VECTOR & \
       ( RSBAC_READ_WRITE_REQUEST_VECTOR | RSBAC_SYSTEM_REQUEST_VECTOR ) ) \
     | RSBAC_ACL_SYSADM_RIGHTS_VECTOR }

#define RSBAC_ACL_GENERAL_DEV_ENTRY \
   { ACLS_GROUP, \
     RSBAC_ACL_GROUP_EVERYONE, \
     ( RSBAC_DEV_REQUEST_VECTOR & RSBAC_READ_WRITE_REQUEST_VECTOR ) | RSBAC_ACL_GEN_RIGHTS_VECTOR }

#define RSBAC_ACL_ACMAN_DEV_ENTRY \
   { ACLS_USER, \
     RSBAC_SECOFF_UID, \
     ( RSBAC_DEV_REQUEST_VECTOR & \
       ( RSBAC_READ_WRITE_REQUEST_VECTOR | RSBAC_SECURITY_REQUEST_VECTOR ) ) \
     | RSBAC_ACL_ACMAN_RIGHTS_VECTOR }

#define RSBAC_ACL_SYSADM_DEV_ENTRY \
   { ACLS_USER, \
     RSBAC_SYSADM_UID, \
     ( RSBAC_DEV_REQUEST_VECTOR & \
       ( RSBAC_READ_WRITE_REQUEST_VECTOR | RSBAC_SYSTEM_REQUEST_VECTOR ) ) \
     | RSBAC_ACL_SYSADM_RIGHTS_VECTOR }

#define RSBAC_ACL_GENERAL_IPC_ENTRY \
   { ACLS_GROUP, \
     RSBAC_ACL_GROUP_EVERYONE, \
     ( RSBAC_IPC_REQUEST_VECTOR & RSBAC_READ_WRITE_REQUEST_VECTOR ) | RSBAC_ACL_GEN_RIGHTS_VECTOR }

#define RSBAC_ACL_ACMAN_IPC_ENTRY \
   { ACLS_USER, \
     RSBAC_SECOFF_UID, \
     ( RSBAC_IPC_REQUEST_VECTOR & \
       ( RSBAC_READ_WRITE_REQUEST_VECTOR | RSBAC_SECURITY_REQUEST_VECTOR ) ) \
     | RSBAC_ACL_ACMAN_RIGHTS_VECTOR }

#define RSBAC_ACL_SYSADM_IPC_ENTRY \
   { ACLS_USER, \
     RSBAC_SYSADM_UID, \
     ( RSBAC_IPC_REQUEST_VECTOR & \
       ( RSBAC_READ_WRITE_REQUEST_VECTOR | RSBAC_SYSTEM_REQUEST_VECTOR ) ) \
     | RSBAC_ACL_SYSADM_RIGHTS_VECTOR }

#define RSBAC_ACL_GENERAL_SCD_ENTRY \
   { ACLS_GROUP, \
     RSBAC_ACL_GROUP_EVERYONE, \
     ( RSBAC_SCD_REQUEST_VECTOR & \
       ( RSBAC_READ_WRITE_REQUEST_VECTOR | ((rsbac_request_vector_t) 1 << R_MODIFY_SYSTEM_DATA) ) \
     ) \
     | RSBAC_ACL_GEN_RIGHTS_VECTOR \
   }

#ifdef CONFIG_RSBAC_USER_MOD_IOPERM
#define RSBAC_ACL_GENERAL_SCD_IOPORTS_ENTRY \
   { ACLS_GROUP, \
     RSBAC_ACL_GROUP_EVERYONE, \
     ((rsbac_request_vector_t) 1 << R_MODIFY_PERMISSIONS_DATA) \
   }
#endif

#define RSBAC_ACL_ACMAN_SCD_ENTRY \
   { ACLS_USER, \
     RSBAC_SECOFF_UID, \
     ( RSBAC_SCD_REQUEST_VECTOR & \
       ( RSBAC_READ_WRITE_REQUEST_VECTOR | RSBAC_SECURITY_REQUEST_VECTOR ) ) \
     | RSBAC_ACL_ACMAN_RIGHTS_VECTOR }

#define RSBAC_ACL_ACMAN_SCD_OTHER_ENTRY \
   { ACLS_USER, \
     RSBAC_SECOFF_UID, \
     ( RSBAC_NONE_REQUEST_VECTOR & \
       ( \
          ((rsbac_request_vector_t) 1 << R_EXECUTE) \
        | ((rsbac_request_vector_t) 1 << R_MODIFY_ATTRIBUTE) \
        | ((rsbac_request_vector_t) 1 << R_READ_ATTRIBUTE) \
        | ((rsbac_request_vector_t) 1 << R_SWITCH_LOG) \
        | ((rsbac_request_vector_t) 1 << R_SWITCH_MODULE) \
       ) \
     ) \
     | RSBAC_ACL_ACMAN_RIGHTS_VECTOR }

#define RSBAC_ACL_SYSADM_SCD_ENTRY \
   { ACLS_USER, \
     RSBAC_SYSADM_UID, \
     ( RSBAC_SCD_REQUEST_VECTOR & \
       ( \
          ((rsbac_request_vector_t) 1 << R_GET_PERMISSIONS_DATA) \
        | ((rsbac_request_vector_t) 1 << R_GET_STATUS_DATA) \
        | ((rsbac_request_vector_t) 1 << R_MODIFY_PERMISSIONS_DATA) \
        | ((rsbac_request_vector_t) 1 << R_MODIFY_SYSTEM_DATA) \
       ) \
     ) \
     | RSBAC_ACL_SYSADM_RIGHTS_VECTOR }

#define RSBAC_ACL_SYSADM_SCD_OTHER_ENTRY \
   { ACLS_USER, \
     RSBAC_SYSADM_UID, \
     ( RSBAC_NONE_REQUEST_VECTOR & \
       ( \
          ((rsbac_request_vector_t) 1 << R_ADD_TO_KERNEL) \
        | ((rsbac_request_vector_t) 1 << R_CHANGE_GROUP) \
        | ((rsbac_request_vector_t) 1 << R_CHANGE_OWNER) \
        | ((rsbac_request_vector_t) 1 << R_EXECUTE) \
        | ((rsbac_request_vector_t) 1 << R_MOUNT) \
        | ((rsbac_request_vector_t) 1 << R_REMOVE_FROM_KERNEL) \
        | ((rsbac_request_vector_t) 1 << R_UMOUNT) \
        | ((rsbac_request_vector_t) 1 << R_SHUTDOWN) \
       ) \
     ) \
     | RSBAC_ACL_SYSADM_RIGHTS_VECTOR }

#define RSBAC_ACL_ACMAN_U_ENTRY \
   { ACLS_USER, \
     RSBAC_SECOFF_UID, \
     RSBAC_ACL_USER_RIGHTS_VECTOR \
     | RSBAC_ACL_ACMAN_RIGHTS_VECTOR }

#define RSBAC_ACL_SYSADM_U_ENTRY \
   { ACLS_USER, \
     RSBAC_SYSADM_UID, \
     RSBAC_ACL_RIGHTS_VECTOR(R_READ_ATTRIBUTE) \
     | RSBAC_ACL_SYSADM_RIGHTS_VECTOR }

#define RSBAC_ACL_GENERAL_P_ENTRY \
   { ACLS_GROUP, \
     RSBAC_ACL_GROUP_EVERYONE, \
     ( RSBAC_PROCESS_REQUEST_VECTOR & RSBAC_READ_WRITE_REQUEST_VECTOR ) | RSBAC_ACL_GEN_RIGHTS_VECTOR }

#define RSBAC_ACL_ACMAN_P_ENTRY \
   { ACLS_USER, \
     RSBAC_SECOFF_UID, \
     ( RSBAC_PROCESS_REQUEST_VECTOR & \
       ( RSBAC_READ_WRITE_REQUEST_VECTOR | RSBAC_SECURITY_REQUEST_VECTOR ) ) \
     | RSBAC_ACL_ACMAN_RIGHTS_VECTOR }

#define RSBAC_ACL_SYSADM_P_ENTRY \
   { ACLS_USER, \
     RSBAC_SYSADM_UID, \
     ( RSBAC_PROCESS_REQUEST_VECTOR & \
       ( RSBAC_READ_WRITE_REQUEST_VECTOR | RSBAC_SYSTEM_REQUEST_VECTOR ) ) \
     | RSBAC_ACL_SYSADM_RIGHTS_VECTOR }

/**********************************************/
/* Lists of ACL / General subitems            */
/**********************************************/

/* Each list represents sets of ACL entries, using a set-id and a sublist each */

#define RSBAC_ACL_VERSION 1

struct rsbac_acl_sublist_item_t
    {
      struct rsbac_acl_entry_t          entry;
      struct rsbac_acl_sublist_item_t * prev;
      struct rsbac_acl_sublist_item_t * next;
    };

/**********************************************/
/* ACL and device entries for File/Dir ACL    */
/**********************************************/

#define RSBAC_ACL_FD_FILENAME "acl_fd."
#define RSBAC_ACL_DEF_FD_FILENAME "acl_fd.def"
#define RSBAC_ACL_NR_FD_LISTS 10

struct rsbac_acl_fd_list_item_t
    {
             u_long                       id;
             rsbac_acl_rights_vector_t    mask;
             u_int                        sublist_length;
      struct rsbac_acl_sublist_item_t   * sublist_head;
      struct rsbac_acl_sublist_item_t   * sublist_tail;
      struct rsbac_acl_fd_list_item_t   * prev;
      struct rsbac_acl_fd_list_item_t   * next;
    };

struct rsbac_acl_fd_list_head_t
    {
      struct rsbac_acl_fd_list_item_t * head;
      struct rsbac_acl_fd_list_item_t * tail;
      struct rsbac_acl_fd_list_item_t * curr;
             rwlock_t                   lock;
             u_int                      count;
             boolean                    dirty;
    };

/* The list of devices is also a double linked list, so we define list    */
/* items and a list head.                                                 */

struct rsbac_acl_device_list_item_t
    {
      kdev_t                                id;  /* set to 0 before deletion */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
      struct dentry                       * d_covers;
#endif
      struct rsbac_acl_fd_list_head_t       head_table[RSBAC_ACL_NR_FD_LISTS];
      struct rsbac_acl_device_list_item_t * prev;
      struct rsbac_acl_device_list_item_t * next;
      boolean                               no_write;
    };
    
/* To provide consistency we use spinlocks for all list accesses. The     */
/* 'curr' entry is used to avoid repeated lookups for the same item.       */    
    
struct rsbac_acl_device_list_head_t
    {
      struct rsbac_acl_device_list_item_t * head;
      struct rsbac_acl_device_list_item_t * tail;
      struct rsbac_acl_device_list_item_t * curr;
      rwlock_t                              lock;
      u_int                                 count;
    };


/**********************************************/
/* ACL entries for Device ACL                 */
/**********************************************/

#define RSBAC_ACL_DEV_FILENAME "acl_dev"
#define RSBAC_ACL_DEF_DEV_FILENAME "acl_dev.def"

struct rsbac_acl_dev_list_item_t
    {
      struct rsbac_dev_t                  id;
             rsbac_acl_rights_vector_t    mask;
             u_int                        sublist_length;
      struct rsbac_acl_sublist_item_t   * sublist_head;
      struct rsbac_acl_sublist_item_t   * sublist_tail;
      struct rsbac_acl_dev_list_item_t  * prev;
      struct rsbac_acl_dev_list_item_t  * next;
    };

struct rsbac_acl_dev_list_head_t
    {
      struct rsbac_acl_dev_list_item_t * head;
      struct rsbac_acl_dev_list_item_t * tail;
      struct rsbac_acl_dev_list_item_t * curr;
             rwlock_t                    lock;
             u_int                       count;
             boolean                     dirty;
             boolean                     no_write;
    };

/**********************************************/
/* ACL entries for IPC ACL                    */
/**********************************************/

#define RSBAC_ACL_DEF_IPC_FILENAME "acl_ipc.def"

struct rsbac_acl_ipc_list_item_t
    {
      struct rsbac_ipc_t                  id;
             rsbac_acl_rights_vector_t    mask;
             u_int                        sublist_length;
      struct rsbac_acl_sublist_item_t   * sublist_head;
      struct rsbac_acl_sublist_item_t   * sublist_tail;
      struct rsbac_acl_ipc_list_item_t  * prev;
      struct rsbac_acl_ipc_list_item_t  * next;
    };

struct rsbac_acl_ipc_list_head_t
    {
      struct rsbac_acl_ipc_list_item_t * head;
      struct rsbac_acl_ipc_list_item_t * tail;
      struct rsbac_acl_ipc_list_item_t * curr;
             rwlock_t                    lock;
             u_int                       count;
    };

/**********************************************/
/* ACL entries for SCD ACL                    */
/**********************************************/

#define RSBAC_ACL_SCD_FILENAME "acl_scd"
#define RSBAC_ACL_DEF_SCD_FILENAME "acl_scd.def"

struct rsbac_acl_scd_list_item_t
    {
             __u8                         id;  /* enum rsbac_acl_scd_type_t */
             rsbac_acl_rights_vector_t    mask;
             u_int                        sublist_length;
      struct rsbac_acl_sublist_item_t   * sublist_head;
      struct rsbac_acl_sublist_item_t   * sublist_tail;
      struct rsbac_acl_scd_list_item_t  * prev;
      struct rsbac_acl_scd_list_item_t  * next;
    };

struct rsbac_acl_scd_list_head_t
    {
      struct rsbac_acl_scd_list_item_t * head;
      struct rsbac_acl_scd_list_item_t * tail;
      struct rsbac_acl_scd_list_item_t * curr;
             rwlock_t                    lock;
             u_int                       count;
             boolean                     dirty;
             boolean                     no_write;
    };

/**********************************************/
/* ACL entries for user ACL                   */
/**********************************************/

#define RSBAC_ACL_DEF_U_FILENAME "acl_u.def"

struct rsbac_acl_u_list_item_t
    {
             rsbac_uid_t                  id;
             rsbac_acl_rights_vector_t    mask;
             u_int                        sublist_length;
      struct rsbac_acl_sublist_item_t   * sublist_head;
      struct rsbac_acl_sublist_item_t   * sublist_tail;
      struct rsbac_acl_u_list_item_t    * prev;
      struct rsbac_acl_u_list_item_t    * next;
    };

struct rsbac_acl_u_list_head_t
    {
      struct rsbac_acl_u_list_item_t   * head;
      struct rsbac_acl_u_list_item_t   * tail;
      struct rsbac_acl_u_list_item_t   * curr;
             rwlock_t                    lock;
             u_int                       count;
    };


/**********************************************/
/* ACL entries for process ACL                */
/**********************************************/

#define RSBAC_ACL_DEF_P_FILENAME "acl_p.def"

struct rsbac_acl_p_list_item_t
    {
             rsbac_pid_t                  id;
             rsbac_acl_rights_vector_t    mask;
             u_int                        sublist_length;
      struct rsbac_acl_sublist_item_t   * sublist_head;
      struct rsbac_acl_sublist_item_t   * sublist_tail;
      struct rsbac_acl_p_list_item_t    * prev;
      struct rsbac_acl_p_list_item_t    * next;
    };

struct rsbac_acl_p_list_head_t
    {
      struct rsbac_acl_p_list_item_t   * head;
      struct rsbac_acl_p_list_item_t   * tail;
      struct rsbac_acl_p_list_item_t   * curr;
             rwlock_t                    lock;
             u_int                       count;
    };


/**********************************************/
/* Group Lists                                */
/**********************************************/

#define RSBAC_ACL_GROUP_FILENAME "acl_grp"
#define RSBAC_ACL_GM_FILENAME "acl_gm"

struct rsbac_acl_group_list_item_t
    {
      struct rsbac_acl_group_entry_t       entry;
      struct rsbac_acl_group_list_item_t * prev;
      struct rsbac_acl_group_list_item_t * next;
    };

struct rsbac_acl_group_list_head_t
    {
      struct rsbac_acl_group_list_item_t * head;
      struct rsbac_acl_group_list_item_t * tail;
      struct rsbac_acl_group_list_item_t * curr;
             rsbac_acl_group_id_t          last_new;
             rwlock_t                      lock;
             u_int                         count;
             boolean                       dirty;
             boolean                       no_write;
    };

#define RSBAC_ACL_GM_VERSION 2
#define RSBAC_ACL_OLD_GM_VERSION 1

/* group members - organized by user */
struct rsbac_acl_gm_sublist_item_t
    {
      rsbac_acl_group_id_t                 group;
      struct rsbac_acl_gm_sublist_item_t * prev;
      struct rsbac_acl_gm_sublist_item_t * next;
    };

struct rsbac_acl_gm_list_item_t
    {
             rsbac_uid_t                   user;
             u_int                         sublist_length;
      struct rsbac_acl_gm_sublist_item_t * sublist_head;
      struct rsbac_acl_gm_sublist_item_t * sublist_tail;
      struct rsbac_acl_gm_list_item_t    * prev;
      struct rsbac_acl_gm_list_item_t    * next;
    };

struct rsbac_acl_gm_list_head_t
    {
      struct rsbac_acl_gm_list_item_t  * head;
      struct rsbac_acl_gm_list_item_t  * tail;
      struct rsbac_acl_gm_list_item_t  * curr;
             rwlock_t                    lock;
             u_int                       count;
             boolean                     dirty;
             boolean                     no_write;
    };


#endif
