/**************************************/
/* Rule Set Based Access Control      */
/* Author and (c) 1999-2002: Amon Ott */
/* Data structures                    */
/* Last modified: 25/Feb/2002         */
/**************************************/

#ifndef __RSBAC_DATA_STRUC_H
#define __RSBAC_DATA_STRUC_H

#ifdef __KERNEL__   /* only include in kernel code */
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/wait.h>
#include <linux/interrupt.h>
#include <asm/semaphore.h>
#include <rsbac/types.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
#include <asm/spinlock.h>
#else
#include <linux/spinlock.h>
#endif
#include <rsbac/pm_types.h>
#include <rsbac/rc_types.h>
#include <rsbac/aci.h>
#include <rsbac/debug.h>
#include <rsbac/lists.h>
#endif /* __KERNEL__ */

#include <rsbac/ms_strings.h>

/* First of all we define dirname and filenames for saving the ACIs to disk. */
/* The path must be a valid single dir name! Each mounted device gets its    */
/* own file set, residing in 'DEVICE_ROOT/RSBAC_ACI_PATH/'.                  */
/* The FD filename gets a suffix for the list number (see RSBAC_NR_FD_LISTS),*/
/* so we have RSBAC_NR_FD_LISTS files for file/dir ACI and one for user ACI. */
/* The dynamic data structures for PM, RC and ACL are kept in their own files.*/
/* All user access to these files will be denied.                            */
/* Backups are kept in FILENAMEb.                                            */

#ifdef __KERNEL__
#define RSBAC_LOG_BUF_LEN (16384)

#define RSBAC_ACI_PATH          "rsbac.dat"

#define RSBAC_GEN_FD_NAME       "fd_gen."
#define RSBAC_MAC_FD_NAME       "fd_mac."
#define RSBAC_FC_FD_NAME        "fd_fc."
#define RSBAC_SIM_FD_NAME       "fd_sim."
#define RSBAC_PM_FD_NAME        "fd_pm."
#define RSBAC_MS_FD_NAME        "fd_mst."
#define RSBAC_MS_SCANNED_FD_NAME "fd_mss."
#define RSBAC_FF_FD_NAME        "fd_ff."
#define RSBAC_RC_FD_NAME        "fd_rc."
#define RSBAC_AUTH_FD_NAME      "fd_auth."
#define RSBAC_CAP_FD_NAME       "fd_cap."

#define RSBAC_ACI_USER_NAME     "useraci"
/* dir creation mode for discretionary access control: rwx for user only*/
#define RSBAC_ACI_DIR_MODE       (S_IFDIR | S_IRWXU)
/* file creation mode for discretionary access control: rw for user only*/
#define RSBAC_ACI_FILE_MODE      (S_IFREG | S_IRUSR | S_IWUSR)
/* minimal mem chunk size available to try write_partial_fd_list, else defer */
#define RSBAC_MIN_WRITE_FD_BUF_LEN 32768
/* max size for write_chunks */
#define RSBAC_MAX_WRITE_CHUNK ((1 << 15) - 1)

/* Since we will use a simple hash function for file/dir aci, we define   */
/* the table size here. WARNING: If this value is changed, aci data on    */
/* disk may become invalid and should be converted explicitly using       */
/* rsbac_change_nr kernel parameter on next boot!                         */
/* To remain compliant with all file systems, this value should not       */
/* exceed 100 (8.3 convention: 0-99 + b). */

#define RSBAC_GEN_NR_FD_LISTS  8
#define RSBAC_MAC_NR_FD_LISTS  32
#define RSBAC_FC_NR_FD_LISTS   8
#define RSBAC_SIM_NR_FD_LISTS  8
#define RSBAC_PM_NR_FD_LISTS   16
#define RSBAC_MS_NR_FD_LISTS   2
#define RSBAC_MS_SCANNED_NR_FD_LISTS 32
#define RSBAC_FF_NR_FD_LISTS   8
#define RSBAC_RC_NR_FD_LISTS   16
#define RSBAC_AUTH_NR_FD_LISTS 2
#define RSBAC_CAP_NR_FD_LISTS  4

#ifdef CONFIG_RSBAC_INIT_THREAD
/* Check and set init timeout */
#if CONFIG_RSBAC_MAX_INIT_TIME >= 5
#define RSBAC_MAX_INIT_TIME CONFIG_RSBAC_MAX_INIT_TIME
#else
#define RSBAC_MAX_INIT_TIME 5
#endif
#endif /* INIT_THREAD */

#endif /* __KERNEL__ */

/* The following structures privide attributes for all possible targets.  */
/* The data structures are kept in double linked lists, and are optimized */
/* by hash functions.                                                     */

/* Only ATTRIBUTES are saved in those structures, that are saved to disk, */
/* because saving sublists means breaking up the structures for every     */
/* single list.                                                           */
/* If a list of policy dependant items is to be stored, this is done in   */
/* the policy dependant data structures. Here only an ID as a handle is   */
/* supported.                                                             */

/* OK, first we define the file/dir ACI, holding all file/dir information */
/* the ADF needs for decisions.                                           */

/* Caution: whenever ACI changes, version and old_version should be increased!            */

#define RSBAC_GEN_FD_ACI_VERSION 3
#define RSBAC_GEN_FD_ACI_KEY 1001
struct rsbac_gen_fd_aci_t            
  {
    rsbac_log_array_t           log_array_low;    /* file/dir based logging, */
    rsbac_log_array_t           log_array_high;   /* high and low bits */
    rsbac_request_vector_t      log_program_based; /* Program based logging */
    rsbac_enum_t                symlink_add_uid;
    rsbac_enum_t                symlink_add_rc_role;
    rsbac_enum_t                linux_dac_disable;
  };
#define DEFAULT_GEN_FD_ACI \
    { \
      -1,                   /* log_array_low  (log request based) */ \
      -1,                   /* log_array_high (log request based) */ \
      0,                    /* log_program_based (don't log specially) */ \
      FALSE,                /* symlink_add_uid (don't add uid) */ \
      FALSE,                /* symlink_add_rc_role (don't add RC role) */ \
      LDD_inherit           /* linux_dac_disable (inherit from parent) */ \
    }

#define DEFAULT_GEN_ROOT_DIR_ACI \
    { \
      -1,                   /* log_array_low  (log request based) */ \
      -1,                   /* log_array_high (log request based) */ \
      0,                    /* log_program_based (don't log specially) */ \
      FALSE,                /* symlink_add_uid (don't add uid) */ \
      FALSE,                /* symlink_add_rc_role (don't add RC role) */ \
      LDD_false             /* linux_dac_disable (do not disable) */ \
    }

#define RSBAC_GEN_FD_OLD_ACI_VERSION 2
struct rsbac_gen_fd_old_aci_t            
  {
    rsbac_log_array_t           log_array_low;    /* file/dir based logging, */
    rsbac_log_array_t           log_array_high;   /* high and low bits */
    rsbac_request_vector_t      log_program_based; /* Program based logging */
    rsbac_enum_t                symlink_add_uid;
  };

#define RSBAC_GEN_FD_OLD_OLD_ACI_VERSION 1
struct rsbac_gen_fd_old_old_aci_t            
  {
    rsbac_log_array_t           log_array_low;    /* file/dir based logging, */
    rsbac_log_array_t           log_array_high;   /* high and low bits */
    rsbac_request_vector_t      log_program_based; /* Program based logging */
  };


#if defined(CONFIG_RSBAC_MAC) || defined(CONFIG_RSBAC_MAC_MAINT)
#define RSBAC_MAC_FD_ACI_VERSION 1
#define RSBAC_MAC_FD_ACI_KEY 1001
struct rsbac_mac_fd_aci_t            
  {
    rsbac_security_level_t      sec_level;        /* MAC */
    rsbac_uid_t                 mac_trusted_for_user; /* MAC (for FILE only) */
    rsbac_mac_category_vector_t mac_categories;   /* MAC category set */
  };

#define DEFAULT_MAC_FD_ACI_INH \
    { \
      SL_inherit,           /* security_level (MAC) */ \
      RSBAC_NO_USER,        /* mac_trusted_for_user (MAC) */ \
      RSBAC_MAC_INHERIT_CAT_VECTOR, /* mac_categories (MAC) */ \
    }
#define DEFAULT_MAC_FD_ACI_NO_INH \
    { \
      SL_unclassified,    /* security_level (MAC) */ \
      RSBAC_NO_USER,      /* mac_trusted_for_user (MAC) */ \
      RSBAC_MAC_DEF_CAT_VECTOR, /* mac_categories (MAC) */ \
    }

#ifdef CONFIG_RSBAC_MAC_DEF_INHERIT
#define DEFAULT_MAC_FD_ACI DEFAULT_MAC_FD_ACI_INH
#else
#define DEFAULT_MAC_FD_ACI DEFAULT_MAC_FD_ACI_NO_INH
#endif /* MAC_DEF_INHERIT */

#define DEFAULT_MAC_ROOT_DIR_ACI \
    { \
      SL_unclassified,    /* security_level (MAC) */ \
      RSBAC_NO_USER,      /* mac_trusted_for_user (MAC) */ \
      RSBAC_MAC_DEF_CAT_VECTOR, /* mac_categories (MAC) */ \
    }
#endif

#if defined(CONFIG_RSBAC_FC) || defined(CONFIG_RSBAC_FC_MAINT)
#define RSBAC_FC_FD_ACI_VERSION 1
#define RSBAC_FC_FD_ACI_KEY 1001
#endif

#if defined(CONFIG_RSBAC_SIM) || defined(CONFIG_RSBAC_SIM_MAINT)
#define RSBAC_SIM_FD_ACI_VERSION 1
#define RSBAC_SIM_FD_ACI_KEY 1001
#endif

#if defined(CONFIG_RSBAC_PM) || defined(CONFIG_RSBAC_PM_MAINT)
#define RSBAC_PM_FD_ACI_VERSION 1
#define RSBAC_PM_FD_ACI_KEY 1001
struct rsbac_pm_fd_aci_t            
  {
    rsbac_pm_object_class_id_t  pm_object_class;  /* PM  */
    rsbac_pm_tp_id_t            pm_tp;            /* PM (for FILE only) */
    rsbac_pm_object_type_int_t  pm_object_type;   /* PM (enum rsbac_pm_object_type_t -> __u8) */
  };

#define DEFAULT_PM_FD_ACI \
    { \
      0,                    /* pm_tp_id       (PM) */ \
      0,                    /* pm_object_class_id (PM) */ \
      PO_none,              /* pm_object_type  (PM) */ \
    }
#endif

#if defined(CONFIG_RSBAC_MS) || defined(CONFIG_RSBAC_MS_MAINT)
#define RSBAC_MS_FD_ACI_VERSION 2
#define RSBAC_MS_FD_ACI_KEY 1001
#define RSBAC_MS_SCANNED_FD_ACI_VERSION 2
struct rsbac_ms_fd_aci_t            
  {
    __u8                        ms_trusted;       /* MS (for FILE only) (boolean) */
    rsbac_ms_sock_trusted_int_t ms_sock_trusted_tcp; /* MS (for FILE only) (enum rsbac_ms_sock_trusted_t) */
    rsbac_ms_sock_trusted_int_t ms_sock_trusted_udp; /* MS (for FILE only) (enum rsbac_ms_sock_trusted_t) */
  };

#define DEFAULT_MS_FD_ACI \
    { \
      FALSE,                /* ms_trusted      (MS) */ \
      MS_not_trusted,       /* ms_sock_trusted_tcp (MS) */ \
      MS_not_trusted,       /* ms_sock_trusted_udp (MS) */ \
    }
#endif

#if defined(CONFIG_RSBAC_FF) || defined(CONFIG_RSBAC_FF_MAINT)
#define RSBAC_FF_FD_ACI_VERSION 1
#define RSBAC_FF_FD_ACI_KEY 1001
#endif

#if defined(CONFIG_RSBAC_RC) || defined(CONFIG_RSBAC_RC_MAINT)
#define RSBAC_RC_FD_ACI_VERSION 1
#define RSBAC_RC_FD_ACI_KEY 1001
struct rsbac_rc_fd_aci_t            
  {
    rsbac_rc_type_id_t          rc_type_fd;       /* RC */
    rsbac_rc_role_id_t          rc_force_role;    /* RC */
    rsbac_rc_role_id_t          rc_initial_role;  /* RC */
  };

#define DEFAULT_RC_FD_ACI \
    { \
      RC_type_inherit_parent, /* rc_type (RC): inherit from parent dir */ \
      RC_default_force_role, /* rc_force_role (RC): (see rc_types.h) */ \
      RC_default_initial_role, /* rc_initial_role (RC): (see rc_types.h) */ \
    }
#define DEFAULT_RC_ROOT_DIR_ACI \
    { \
      RSBAC_RC_GENERAL_TYPE, /* rc_type (RC): general fd type */ \
      RC_default_root_dir_force_role,  /* rc_force_role (RC): (see rc_types.h) */ \
      RC_default_root_dir_initial_role, /* rc_initial_role (RC): (see rc_types.h) */ \
    }
#endif

#if defined(CONFIG_RSBAC_AUTH) || defined(CONFIG_RSBAC_AUTH_MAINT)
#define RSBAC_AUTH_FD_ACI_VERSION 1
#define RSBAC_AUTH_FD_ACI_KEY 1001
struct rsbac_auth_fd_aci_t            
  {
    __u8                        auth_may_setuid;  /* AUTH (boolean) */
    __u8                        auth_may_set_cap; /* AUTH (boolean) */
  };

#define DEFAULT_AUTH_FD_ACI \
    { \
      FALSE,                /* auth_may_setuid (AUTH): program may not setuid to any */ \
      FALSE,                /* auth_may_set_cap (AUTH): program may not set setuid */ \
                                  /* capabilities for other processes */ \
    }
#endif

#if defined(CONFIG_RSBAC_CAP) || defined(CONFIG_RSBAC_CAP_MAINT)
#define RSBAC_CAP_FD_ACI_VERSION 1
#define RSBAC_CAP_FD_ACI_KEY 1001
struct rsbac_cap_fd_aci_t            
  {
    rsbac_cap_vector_t          min_caps;      /* Program forced minimum Linux capabilities */
    rsbac_cap_vector_t          max_caps;      /* Program max Linux capabilities */
  };
#define DEFAULT_CAP_FD_ACI \
    { \
      0,                    /* min_caps (none) */ \
      (rsbac_cap_vector_t) -1 /* max_caps (all) */ \
    }
#endif

#define RSBAC_FD_NR_ATTRIBUTES 26
#define RSBAC_FD_ATTR_LIST { \
      A_security_level, \
      A_mac_trusted_for_user, \
      A_mac_categories, \
      A_object_category, \
      A_data_type, \
      A_pm_object_class, \
      A_pm_tp, \
      A_pm_object_type, \
      A_ms_scanned, \
      A_ms_trusted, \
      A_ms_sock_trusted_tcp, \
      A_ms_sock_trusted_udp, \
      A_ff_flags, \
      A_rc_type_fd, \
      A_rc_force_role, \
      A_rc_initial_role, \
      A_auth_may_setuid, \
      A_auth_may_set_cap, \
      A_log_array_low, \
      A_log_array_high, \
      A_log_program_based, \
      A_symlink_add_uid, \
      A_symlink_add_rc_role, \
      A_linux_dac_disable, \
      A_min_caps, \
      A_max_caps \
      }

#ifdef __KERNEL__
struct rsbac_fd_list_handles_t
    {
      rsbac_list_handle_t gen[RSBAC_GEN_NR_FD_LISTS];
#if defined(CONFIG_RSBAC_MAC) || defined(CONFIG_RSBAC_MAC_MAINT)
      rsbac_list_handle_t mac[RSBAC_MAC_NR_FD_LISTS];
#endif
#if defined(CONFIG_RSBAC_FC) || defined(CONFIG_RSBAC_FC_MAINT)
      rsbac_list_handle_t fc[RSBAC_FC_NR_FD_LISTS];
#endif
#if defined(CONFIG_RSBAC_SIM) || defined(CONFIG_RSBAC_SIM_MAINT)
      rsbac_list_handle_t sim[RSBAC_SIM_NR_FD_LISTS];
#endif
#if defined(CONFIG_RSBAC_PM) || defined(CONFIG_RSBAC_PM_MAINT)
      rsbac_list_handle_t pm[RSBAC_PM_NR_FD_LISTS];
#endif
#if defined(CONFIG_RSBAC_MS) || defined(CONFIG_RSBAC_MS_MAINT)
      rsbac_list_handle_t ms[RSBAC_MS_NR_FD_LISTS];
      rsbac_list_handle_t mss[RSBAC_MS_SCANNED_NR_FD_LISTS];
#endif
#if defined(CONFIG_RSBAC_FF) || defined(CONFIG_RSBAC_FF_MAINT)
      rsbac_list_handle_t ff[RSBAC_FF_NR_FD_LISTS];
#endif
#if defined(CONFIG_RSBAC_RC) || defined(CONFIG_RSBAC_RC_MAINT)
      rsbac_list_handle_t rc[RSBAC_RC_NR_FD_LISTS];
#endif
#if defined(CONFIG_RSBAC_AUTH) || defined(CONFIG_RSBAC_AUTH_MAINT)
      rsbac_list_handle_t auth[RSBAC_AUTH_NR_FD_LISTS];
#endif
#if defined(CONFIG_RSBAC_CAP) || defined(CONFIG_RSBAC_CAP_MAINT)
      rsbac_list_handle_t cap[RSBAC_CAP_NR_FD_LISTS];
#endif
    };

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

struct rsbac_device_list_item_t
    {
      kdev_t                              id;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
      struct dentry                     * d_covers;
      u_int                               mount_count;
#endif
      struct rsbac_fd_list_handles_t      handles;
      struct dentry                     * rsbac_dir_dentry_p;
      struct super_block                * sb_p;
      rsbac_inode_nr_t                    rsbac_dir_inode;
      struct rsbac_device_list_item_t   * prev;
      struct rsbac_device_list_item_t   * next;
    };
    
/* 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_device_list_head_t
    {
      struct rsbac_device_list_item_t * head;
      struct rsbac_device_list_item_t * tail;
      struct rsbac_device_list_item_t * curr;
      rwlock_t                          lock;
      u_int                             count;
    };

#endif /* __KERNEL__ */

/******************************/
/* OK, now we define the block/char device ACI, holding all dev information */
/* the ADF needs for decisions.                                           */

#define RSBAC_GEN_ACI_DEV_NAME   "dev_gen"
#define RSBAC_MAC_ACI_DEV_NAME   "dev_mac"
#define RSBAC_FC_ACI_DEV_NAME    "dev_fc"
#define RSBAC_SIM_ACI_DEV_NAME   "dev_sim"
#define RSBAC_PM_ACI_DEV_NAME    "dev_pm"
#define RSBAC_RC_ACI_DEV_NAME    "dev_rc"

/* Caution: whenever ACI changes, version should be increased!            */

#define RSBAC_GEN_DEV_ACI_VERSION 1
#define RSBAC_GEN_DEV_ACI_KEY 1001

struct rsbac_gen_dev_aci_t            
  {                                
           rsbac_log_array_t          log_array_low;   /* dev based logging, */
           rsbac_log_array_t          log_array_high;  /* high and low bits */
  };
#define DEFAULT_GEN_DEV_ACI \
    { \
      -1,                 /* log_array_low  (adf) (log request based) */ \
      -1                  /* log_array_high (adf) (log request based) */ \
    }

#if defined(CONFIG_RSBAC_MAC) || defined(CONFIG_RSBAC_MAC_MAINT)
#define RSBAC_MAC_DEV_ACI_VERSION 1
#define RSBAC_MAC_DEV_ACI_KEY 1001
struct rsbac_mac_dev_aci_t            
  {                                
           rsbac_security_level_t     sec_level;       /* MAC */
           rsbac_mac_category_vector_t mac_categories;   /* MAC category set */
           __u8                       mac_check;       /* MAC (boolean) */
  };
#define DEFAULT_MAC_DEV_ACI \
    { \
      SL_unclassified,    /* security_level (MAC) */ \
      RSBAC_MAC_DEF_CAT_VECTOR, /* mac_categories (MAC) */ \
      FALSE               /* mac_check      (MAC) */ \
    }
#endif

#if defined(CONFIG_RSBAC_FC) || defined(CONFIG_RSBAC_FC_MAINT)
#define RSBAC_FC_DEV_ACI_VERSION 1
#define RSBAC_FC_DEV_ACI_KEY 1001
#endif

#if defined(CONFIG_RSBAC_SIM) || defined(CONFIG_RSBAC_SIM_MAINT)
#define RSBAC_SIM_DEV_ACI_VERSION 1
#define RSBAC_SIM_DEV_ACI_KEY 1001
#endif

#if defined(CONFIG_RSBAC_PM) || defined(CONFIG_RSBAC_PM_MAINT)
#define RSBAC_PM_DEV_ACI_VERSION 1
#define RSBAC_PM_DEV_ACI_KEY 1001
struct rsbac_pm_dev_aci_t            
  {
    rsbac_pm_object_type_int_t pm_object_type;  /* PM (enum rsbac_pm_object_type_t) */
    rsbac_pm_object_class_id_t pm_object_class; /* dev only */
  };

#define DEFAULT_PM_DEV_ACI \
    { \
      PO_none,            /* pm_object_type  (PM) */ \
      0                   /* pm_object_class_id (PM) */ \
    }
#endif

#if defined(CONFIG_RSBAC_RC) || defined(CONFIG_RSBAC_RC_MAINT)
#define RSBAC_RC_DEV_ACI_VERSION 1
#define RSBAC_RC_DEV_ACI_KEY 1001
#endif

#define RSBAC_DEV_NR_ATTRIBUTES 10
#define RSBAC_DEV_ATTR_LIST { \
      A_security_level, \
      A_mac_categories, \
      A_object_category, \
      A_data_type, \
      A_mac_check, \
      A_pm_object_type, \
      A_pm_object_class, \
      A_rc_type, \
      A_log_array_low, \
      A_log_array_high \
      }

#ifdef __KERNEL__
struct rsbac_dev_handles_t
    {
      rsbac_list_handle_t gen;
#if defined(CONFIG_RSBAC_MAC) || defined(CONFIG_RSBAC_MAC_MAINT)
      rsbac_list_handle_t mac;
#endif
#if defined(CONFIG_RSBAC_FC) || defined(CONFIG_RSBAC_FC_MAINT)
      rsbac_list_handle_t fc;
#endif
#if defined(CONFIG_RSBAC_SIM) || defined(CONFIG_RSBAC_SIM_MAINT)
      rsbac_list_handle_t sim;
#endif
#if defined(CONFIG_RSBAC_PM) || defined(CONFIG_RSBAC_PM_MAINT)
      rsbac_list_handle_t pm;
#endif
#if defined(CONFIG_RSBAC_RC) || defined(CONFIG_RSBAC_RC_MAINT)
      rsbac_list_handle_t rc;
#endif
    };
#endif /* __KERNEL__ */

/**************************************************************************/
/* Next we define the ipc ACI, holding all ipc information                */
/* the ADF needs for decisions.                                           */

#define RSBAC_MAC_ACI_IPC_NAME   "ipc_mac"
#define RSBAC_FC_ACI_IPC_NAME    "ipc_fc"
#define RSBAC_SIM_ACI_IPC_NAME   "ipc_sim"
#define RSBAC_PM_ACI_IPC_NAME    "ipc_pm"
#define RSBAC_RC_ACI_IPC_NAME    "ipc_rc"

#if defined(CONFIG_RSBAC_MAC) || defined(CONFIG_RSBAC_MAC_MAINT)
#define RSBAC_MAC_IPC_ACI_VERSION 1
#define RSBAC_MAC_IPC_ACI_KEY 1001
struct rsbac_mac_ipc_aci_t
    {
      rsbac_security_level_t     sec_level; /* enum old_rsbac_security_level_t / __u8 */
      rsbac_mac_category_vector_t mac_categories;   /* MAC category set */
    };
#define DEFAULT_MAC_IPC_ACI \
    { \
      SL_unclassified,  /* security_level (MAC) */ \
      RSBAC_MAC_DEF_CAT_VECTOR /* mac_categories (MAC) */ \
    }
#endif

#if defined(CONFIG_RSBAC_FC) || defined(CONFIG_RSBAC_FC_MAINT)
#define RSBAC_FC_IPC_ACI_VERSION 1
#define RSBAC_FC_IPC_ACI_KEY 1001
#endif

#if defined(CONFIG_RSBAC_SIM) || defined(CONFIG_RSBAC_SIM_MAINT)
#define RSBAC_SIM_IPC_ACI_VERSION 1
#define RSBAC_SIM_IPC_ACI_KEY 1001
#endif

#if defined(CONFIG_RSBAC_PM) || defined(CONFIG_RSBAC_PM_MAINT)
#define RSBAC_PM_IPC_ACI_VERSION 1
#define RSBAC_PM_IPC_ACI_KEY 1001
struct rsbac_pm_ipc_aci_t
    {
      rsbac_pm_object_class_id_t pm_object_class; /* ipc only */
      rsbac_pm_purpose_id_t      pm_ipc_purpose;
      rsbac_pm_object_type_int_t pm_object_type; /* enum rsbac_pm_object_type_t */
    };
#define DEFAULT_PM_IPC_ACI \
    { \
      RSBAC_PM_IPC_OBJECT_CLASS_ID, /* pm_object_class_id (PM) */ \
      0,                /* pm_ipc_purpose  (PM) */ \
      PO_ipc            /* pm_object_type  (PM) */ \
    }
#endif

#if defined(CONFIG_RSBAC_RC) || defined(CONFIG_RSBAC_RC_MAINT)
#define RSBAC_RC_IPC_ACI_VERSION 1
#define RSBAC_RC_IPC_ACI_KEY 1001
#endif

#define RSBAC_IPC_NR_ATTRIBUTES 13
#define RSBAC_IPC_ATTR_LIST { \
      A_security_level, \
      A_mac_categories, \
      A_object_category, \
      A_data_type, \
      A_pm_object_class, \
      A_pm_ipc_purpose, \
      A_pm_object_type, \
      A_ms_backbuf, \
      A_ms_buflen, \
      A_ms_str_nr, \
      A_ms_str_offset, \
      A_ms_scanned, \
      A_rc_type \
      }

#ifdef __KERNEL__
struct rsbac_ipc_handles_t
    {
#if defined(CONFIG_RSBAC_MAC) || defined(CONFIG_RSBAC_MAC_MAINT)
      rsbac_list_handle_t mac;
#endif
#if defined(CONFIG_RSBAC_FC) || defined(CONFIG_RSBAC_FC_MAINT)
      rsbac_list_handle_t fc;
#endif
#if defined(CONFIG_RSBAC_SIM) || defined(CONFIG_RSBAC_SIM_MAINT)
      rsbac_list_handle_t sim;
#endif
#if defined(CONFIG_RSBAC_PM) || defined(CONFIG_RSBAC_PM_MAINT)
      rsbac_list_handle_t pm;
#endif
#if defined(CONFIG_RSBAC_RC) || defined(CONFIG_RSBAC_RC_MAINT)
      rsbac_list_handle_t rc;
#endif
    };
#endif /* __KERNEL__ */

/*************************************/
/* The user ACI holds all user information the ADF needs. */

#define RSBAC_GEN_ACI_USER_NAME   "u_gen"
#define RSBAC_MAC_ACI_USER_NAME   "u_mac"
#define RSBAC_FC_ACI_USER_NAME    "u_fc"
#define RSBAC_SIM_ACI_USER_NAME   "u_sim"
#define RSBAC_PM_ACI_USER_NAME    "u_pm"
#define RSBAC_MS_ACI_USER_NAME    "u_ms"
#define RSBAC_FF_ACI_USER_NAME    "u_ff"
#define RSBAC_RC_ACI_USER_NAME    "u_rc"
#define RSBAC_AUTH_ACI_USER_NAME  "u_auth"
#define RSBAC_CAP_ACI_USER_NAME   "u_cap"

#define RSBAC_GEN_USER_ACI_VERSION 1
#define RSBAC_GEN_USER_ACI_KEY 1001
struct rsbac_gen_user_aci_t
    {
      rsbac_pseudo_t           pseudo;
      rsbac_request_vector_t   log_user_based; /* User based logging */
    };
#define DEFAULT_GEN_U_ACI \
    { \
      (rsbac_pseudo_t) 0, /* pseudo        (logging) */ \
      0	                  /* log_user_based (adf): no logging */ \
    }

#if defined(CONFIG_RSBAC_MAC) || defined(CONFIG_RSBAC_MAC_MAINT)
#define RSBAC_MAC_USER_ACI_VERSION 1
#define RSBAC_MAC_USER_ACI_KEY 1001
struct rsbac_mac_user_aci_t
    {
      rsbac_security_level_t      access_appr;    /* enum old_rsbac_security_level_t / __u8 */
      rsbac_mac_category_vector_t mac_categories;   /* MAC category set */
      rsbac_system_role_int_t     system_role;    /* enum rsbac_system_role_t */
    };
#define DEFAULT_MAC_U_ACI \
    { \
      SL_unclassified,          /* security_level       (MAC) */ \
      RSBAC_MAC_DEF_CAT_VECTOR, /* mac_categories (MAC) */ \
      SR_user                   /* system_role (MAC) */ \
    }
#define DEFAULT_MAC_U_SYSADM_ACI \
    { \
      SL_unclassified,          /* security_level       (MAC) */ \
      RSBAC_MAC_DEF_CAT_VECTOR, /* mac_categories (MAC) */ \
      SR_administrator          /* system_role (MAC) */ \
    }
#define DEFAULT_MAC_U_SECOFF_ACI \
    { \
      SL_unclassified,          /* security_level       (MAC) */ \
      RSBAC_MAC_DEF_CAT_VECTOR, /* mac_categories (MAC) */ \
      SR_security_officer       /* system_role (MAC) */ \
    }
#endif

#if defined(CONFIG_RSBAC_FC) || defined(CONFIG_RSBAC_FC_MAINT)
#define RSBAC_FC_USER_ACI_VERSION 1
#define RSBAC_FC_USER_ACI_KEY 1001
#endif

#if defined(CONFIG_RSBAC_SIM) || defined(CONFIG_RSBAC_SIM_MAINT)
#define RSBAC_SIM_USER_ACI_VERSION 1
#define RSBAC_SIM_USER_ACI_KEY 1001
#endif

#if defined(CONFIG_RSBAC_PM) || defined(CONFIG_RSBAC_PM_MAINT)
#define RSBAC_PM_USER_ACI_VERSION 1
#define RSBAC_PM_USER_ACI_KEY 1001
struct rsbac_pm_user_aci_t
    {
      rsbac_pm_task_set_id_t   pm_task_set;
      rsbac_pm_role_int_t      pm_role;        /* enum rsbac_pm_role_t */
    };
#define DEFAULT_PM_U_ACI \
    { \
      0,                  /* pm_task_set_id (PM) */ \
      PR_user             /* pm_role (PM) */ \
    }
#define DEFAULT_PM_U_SYSADM_ACI \
    { \
      0,                  /* pm_task_set_id (PM) */ \
      PR_system_admin     /* pm_role (PM) */ \
    }
#define DEFAULT_PM_U_SECOFF_ACI \
    { \
      0,                  /* pm_task_set_id (PM) */ \
      PR_security_officer /* pm_role (PM) */ \
    }
#define DEFAULT_PM_U_DATAPROT_ACI \
    { \
      0,                  /* pm_task_set_id (PM) */ \
      PR_data_protection_officer /* pm_role (PM) */ \
    }
#define DEFAULT_PM_U_TPMAN_ACI \
    { \
      0,            /* pm_task_set_id (PM) */ \
      PR_tp_manager /* pm_role (PM) */ \
    }
#endif

#if defined(CONFIG_RSBAC_MS) || defined(CONFIG_RSBAC_MS_MAINT)
#define RSBAC_MS_USER_ACI_VERSION 1
#define RSBAC_MS_USER_ACI_KEY 1001
#endif

#if defined(CONFIG_RSBAC_FF) || defined(CONFIG_RSBAC_FF_MAINT)
#define RSBAC_FF_USER_ACI_VERSION 1
#define RSBAC_FF_USER_ACI_KEY 1001
#endif

#if defined(CONFIG_RSBAC_RC) || defined(CONFIG_RSBAC_RC_MAINT)
#define RSBAC_RC_USER_ACI_VERSION 1
#define RSBAC_RC_USER_ACI_KEY 1001
#endif

#if defined(CONFIG_RSBAC_AUTH) || defined(CONFIG_RSBAC_AUTH_MAINT)
#define RSBAC_AUTH_USER_ACI_VERSION 1
#define RSBAC_AUTH_USER_ACI_KEY 1001
#endif

#if defined(CONFIG_RSBAC_CAP) || defined(CONFIG_RSBAC_CAP_MAINT)
#define RSBAC_CAP_USER_ACI_VERSION 1
#define RSBAC_CAP_USER_ACI_KEY 1001
struct rsbac_cap_user_aci_t            
  {
    rsbac_system_role_int_t     cap_role;      /* System role for CAP administration */
    rsbac_cap_vector_t          min_caps;      /* User forced minimum Linux capabilities */
    rsbac_cap_vector_t          max_caps;      /* User max Linux capabilities */
  };
#define DEFAULT_CAP_U_ACI \
    { \
      SR_user, \
      0,                    /* min_caps (none) */ \
      (rsbac_cap_vector_t) -1 /* max_caps (all) */ \
    }
#define DEFAULT_CAP_U_SYSADM_ACI \
    { \
      SR_administrator, \
      0,                    /* min_caps (none) */ \
      -1                    /* max_caps (all) */ \
    }
#define DEFAULT_CAP_U_SECOFF_ACI \
    { \
      SR_security_officer, \
      0,                    /* min_caps (none) */ \
      -1                    /* max_caps (all) */ \
    }
#endif

#define RSBAC_USER_NR_ATTRIBUTES 15
#define RSBAC_USER_ATTR_LIST { \
      A_pseudo, \
      A_security_level, \
      A_mac_categories, \
      A_mac_role, \
      A_fc_role, \
      A_sim_role, \
      A_ms_role, \
      A_ff_role, \
      A_auth_role, \
      A_pm_task_set, \
      A_pm_role, \
      A_rc_def_role, \
      A_log_user_based, \
      A_min_caps, \
      A_max_caps \
      }

#ifdef __KERNEL__
struct rsbac_user_handles_t
    {
      rsbac_list_handle_t gen;
#if defined(CONFIG_RSBAC_MAC) || defined(CONFIG_RSBAC_MAC_MAINT)
      rsbac_list_handle_t mac;
#endif
#if defined(CONFIG_RSBAC_FC) || defined(CONFIG_RSBAC_FC_MAINT)
      rsbac_list_handle_t fc;
#endif
#if defined(CONFIG_RSBAC_SIM) || defined(CONFIG_RSBAC_SIM_MAINT)
      rsbac_list_handle_t sim;
#endif
#if defined(CONFIG_RSBAC_PM) || defined(CONFIG_RSBAC_PM_MAINT)
      rsbac_list_handle_t pm;
#endif
#if defined(CONFIG_RSBAC_MS) || defined(CONFIG_RSBAC_MS_MAINT)
      rsbac_list_handle_t ms;
#endif
#if defined(CONFIG_RSBAC_FF) || defined(CONFIG_RSBAC_FF_MAINT)
      rsbac_list_handle_t ff;
#endif
#if defined(CONFIG_RSBAC_RC) || defined(CONFIG_RSBAC_RC_MAINT)
      rsbac_list_handle_t rc;
#endif
#if defined(CONFIG_RSBAC_AUTH) || defined(CONFIG_RSBAC_AUTH_MAINT)
      rsbac_list_handle_t auth;
#endif
#if defined(CONFIG_RSBAC_CAP) || defined(CONFIG_RSBAC_CAP_MAINT)
      rsbac_list_handle_t cap;
#endif
    };
#endif 

/********************************/
/* Process ACI. */

#define RSBAC_GEN_ACI_PROCESS_NAME   "process_gen"
#define RSBAC_MAC_ACI_PROCESS_NAME   "process_mac"
#define RSBAC_PM_ACI_PROCESS_NAME    "process_pm"
#define RSBAC_MS_ACI_PROCESS_NAME    "process_ms"
#define RSBAC_RC_ACI_PROCESS_NAME    "process_rc"
#define RSBAC_AUTH_ACI_PROCESS_NAME    "process_auth"
    
#define RSBAC_GEN_PROCESS_ACI_VERSION 1
#define RSBAC_GEN_PROCESS_ACI_KEY 1001

#if defined(CONFIG_RSBAC_MAC) || defined(CONFIG_RSBAC_MAC_MAINT)
#define RSBAC_MAC_PROCESS_ACI_VERSION 1
#define RSBAC_MAC_PROCESS_ACI_KEY 1001
struct rsbac_mac_process_aci_t
    {
      rsbac_security_level_t      owner_sec_level;     /* enum old_rsbac_security_level_t */
      rsbac_mac_category_vector_t mac_owner_categories; /* MAC category set */
      rsbac_security_level_t      current_sec_level;   /* enum rsbac_security_level_t */
      rsbac_mac_category_vector_t mac_curr_categories; /* MAC current category set */
      rsbac_security_level_t      min_write_open;      /* for *-property, enum rsbac_security_level_t */
      rsbac_mac_category_vector_t min_write_categories; /* MAC, for *-property */
      rsbac_security_level_t      max_read_open;       /* for *-property, enum rsbac_security_level_t */
      rsbac_mac_category_vector_t max_read_categories; /* MAC, for *-property */
      rsbac_boolean_int_t         mac_auto;            /* auto-curr-sec-level?, boolean */
      rsbac_boolean_int_t         mac_trusted;         /* trusted process?, boolean */
    };
#define DEFAULT_MAC_P_ACI \
    { \
      SL_unclassified,    /* owner-sec-level   (MAC) */ \
      RSBAC_MAC_DEF_CAT_VECTOR, /* owner_categories (MAC) */ \
      SL_unclassified,    /* current-sec-level (MAC) */ \
      RSBAC_MAC_DEF_CAT_VECTOR, /* mac_curr_categories (MAC) */ \
      SL_max,             /* min-write-open    (MAC) */ \
      RSBAC_MAC_MAX_CAT_VECTOR, /* min_write_categories (MAC) */ \
      SL_unclassified,    /* max-read-open     (MAC) */ \
      RSBAC_MAC_MIN_CAT_VECTOR, /* max_read_categories (MAC) */ \
      TRUE,               /* auto-mac?         (MAC) */ \
      FALSE               /* trusted?          (MAC) */ \
    }
#define DEFAULT_MAC_P_INIT_ACI \
    { \
      SL_unclassified,    /* owner-sec-level   (MAC) */ \
      RSBAC_MAC_DEF_CAT_VECTOR, /* owner_categories (MAC) */ \
      SL_unclassified,    /* current-sec-level (MAC) */ \
      RSBAC_MAC_DEF_CAT_VECTOR, /* mac_curr_categories (MAC) */ \
      SL_max,             /* min-write-open    (MAC) */ \
      RSBAC_MAC_MAX_CAT_VECTOR, /* min_write_categories (MAC) */ \
      SL_unclassified,    /* max-read-open     (MAC) */ \
      RSBAC_MAC_MIN_CAT_VECTOR, /* max_read_categories (MAC) */ \
      FALSE,              /* auto-mac?         (MAC) */ \
      TRUE                /* trusted?          (MAC) */ \
    }
#endif

#if defined(CONFIG_RSBAC_PM) || defined(CONFIG_RSBAC_PM_MAINT)
#define RSBAC_PM_PROCESS_ACI_VERSION 1
#define RSBAC_PM_PROCESS_ACI_KEY 1001
struct rsbac_pm_process_aci_t
    {
      rsbac_pm_tp_id_t            pm_tp;
      rsbac_pm_task_id_t          pm_current_task;
      rsbac_pm_process_type_int_t pm_process_type;     /* enum rsbac_pm_process_type_t */
    };
#define DEFAULT_PM_P_ACI \
    { \
      0,                  /* PM-TP              (PM) */ \
      0,                  /* PM-current-task    (PM) */ \
      PP_none             /* PM-proc-type       (PM) */ \
    }
#endif

#if defined(CONFIG_RSBAC_MS) || defined(CONFIG_RSBAC_MS_MAINT)
#define RSBAC_MS_PROCESS_ACI_VERSION 1
#define RSBAC_MS_PROCESS_ACI_KEY 1001
struct rsbac_ms_process_aci_t
    {
      rsbac_boolean_int_t         ms_trusted;          /* MS, boolean */
      rsbac_ms_sock_trusted_int_t ms_sock_trusted_tcp; /* MS, enum rsbac_ms_sock_trusted_t */
      rsbac_ms_sock_trusted_int_t ms_sock_trusted_udp; /* MS, enum rsbac_ms_sock_trusted_t */
    };
#define DEFAULT_MS_P_ACI \
    { \
      FALSE,              /* ms_trusted         (MS) */ \
      MS_not_trusted,     /* ms_sock_trusted_tcp (MS) */ \
      MS_not_trusted      /* ms_sock_trusted_udp (MS) */ \
    }
#endif

#if defined(CONFIG_RSBAC_RC) || defined(CONFIG_RSBAC_RC_MAINT)
#define RSBAC_RC_PROCESS_ACI_VERSION 1
#define RSBAC_RC_PROCESS_ACI_KEY 1001
struct rsbac_rc_process_aci_t
    {
      rsbac_rc_role_id_t          rc_role;             /* RC */
      rsbac_rc_type_id_t          rc_type;             /* RC */
      rsbac_rc_role_id_t          rc_force_role;       /* RC */
    };
#define DEFAULT_RC_P_ACI \
    { \
      RSBAC_RC_GENERAL_ROLE, /* rc_role (RC): general role */ \
      RSBAC_RC_GENERAL_TYPE, /* rc_type (RC): general process type */ \
      RC_default_force_role  /* rc_force_role (RC): (see rc_types.h) */ \
    }
#define DEFAULT_RC_P_INIT_ACI \
    { \
      RSBAC_RC_SYSTEM_ADMIN_ROLE, /* rc_role (RC): general role */ \
      RSBAC_RC_GENERAL_TYPE, /* rc_type (RC): general process type */ \
      RC_default_force_role  /* rc_force_role (RC): (see rc_types.h) */ \
    }
#endif

#if defined(CONFIG_RSBAC_AUTH) || defined(CONFIG_RSBAC_AUTH_MAINT)
#define RSBAC_AUTH_PROCESS_ACI_VERSION 1
#define RSBAC_AUTH_PROCESS_ACI_KEY 1001
struct rsbac_auth_process_aci_t
    {
      __u8                        auth_may_setuid;     /* AUTH (boolean) */
      __u8                        auth_may_set_cap;    /* AUTH (boolean) */
    };
#define DEFAULT_AUTH_P_ACI \
    { \
      FALSE,              /* auth_may_setuid (AUTH): program may not setuid to any */ \
      FALSE               /* auth_may_set_cap (AUTH): program may not set setuid */ \
                                   /* capabilities for other processes */ \
    }
#endif

#define RSBAC_PROCESS_NR_ATTRIBUTES 22
#define RSBAC_PROCESS_ATTR_LIST { \
      A_security_level, \
      A_mac_categories, \
      A_current_sec_level, \
      A_mac_curr_categories, \
      A_min_write_open, \
      A_min_write_categories, \
      A_max_read_open, \
      A_max_read_categories, \
      A_mac_auto, \
      A_mac_trusted, \
      A_pm_tp, \
      A_pm_current_task, \
      A_pm_process_type, \
      A_ms_trusted, \
      A_ms_sock_trusted_tcp, \
      A_ms_sock_trusted_udp, \
      A_rc_role, \
      A_rc_type, \
      A_rc_force_role, \
      A_auth_may_setuid, \
      A_auth_may_set_cap, \
      A_log_program_based \
      }

#ifdef __KERNEL__
struct rsbac_process_handles_t
    {
      rsbac_list_handle_t gen;
#if defined(CONFIG_RSBAC_MAC) || defined(CONFIG_RSBAC_MAC_MAINT)
      rsbac_list_handle_t mac;
#endif
#if defined(CONFIG_RSBAC_PM) || defined(CONFIG_RSBAC_PM_MAINT)
      rsbac_list_handle_t pm;
#endif
#if defined(CONFIG_RSBAC_MS) || defined(CONFIG_RSBAC_MS_MAINT)
      rsbac_list_handle_t ms;
#endif
#if defined(CONFIG_RSBAC_RC) || defined(CONFIG_RSBAC_RC_MAINT)
      rsbac_list_handle_t rc;
#endif
#if defined(CONFIG_RSBAC_AUTH) || defined(CONFIG_RSBAC_AUTH_MAINT)
      rsbac_list_handle_t auth;
#endif
    };
#endif /* __KERNEL__ */


/********************************/
/* NETDEV ACI */

#define RSBAC_GEN_ACI_NETDEV_NAME   "nd_gen"
#define RSBAC_RC_ACI_NETDEV_NAME    "nd_rc"

#define RSBAC_GEN_NETDEV_ACI_VERSION 1
#define RSBAC_GEN_NETDEV_ACI_KEY 1001
struct rsbac_gen_netdev_aci_t
    {
      rsbac_log_array_t           log_array_low;    /* netdev based logging, */
      rsbac_log_array_t           log_array_high;   /* high and low bits */
    };
#define DEFAULT_GEN_NETDEV_ACI \
    { \
      -1,                   /* log_array_low  (log request based) */ \
      -1                    /* log_array_high (log request based) */ \
    }

#if defined(CONFIG_RSBAC_RC) || defined(CONFIG_RSBAC_RC_MAINT)
#define RSBAC_RC_NETDEV_ACI_VERSION 1
#define RSBAC_RC_NETDEV_ACI_KEY 1001
#endif

#define RSBAC_NETDEV_NR_ATTRIBUTES 3
#define RSBAC_NETDEV_ATTR_LIST { \
      A_rc_type, \
      A_log_array_low, \
      A_log_array_high \
      }

#ifdef __KERNEL__
struct rsbac_netdev_handles_t
    {
#if defined(CONFIG_RSBAC_IND_NETDEV_LOG)
      rsbac_list_handle_t gen;
#endif
#if defined(CONFIG_RSBAC_RC) || defined(CONFIG_RSBAC_RC_MAINT)
      rsbac_list_handle_t rc;
#endif
    };
#endif /* __KERNEL__ */

/********************************/
/* NETTEMP ACI */

#define RSBAC_GEN_ACI_NETTEMP_NAME   "nt_gen"
#define RSBAC_MAC_ACI_NETTEMP_NAME   "nt_mac"
#define RSBAC_FC_ACI_NETTEMP_NAME    "nt_fc"
#define RSBAC_SIM_ACI_NETTEMP_NAME   "nt_sim"
#define RSBAC_PM_ACI_NETTEMP_NAME    "nt_pm"
#define RSBAC_RC_ACI_NETTEMP_NAME    "nt_rc"

#define RSBAC_MAC_ACI_LNETOBJ_NAME   "lnetobj_mac"
#define RSBAC_FC_ACI_LNETOBJ_NAME    "lnetobj_fc"
#define RSBAC_SIM_ACI_LNETOBJ_NAME   "lnetobj_sim"
#define RSBAC_PM_ACI_LNETOBJ_NAME    "lnetobj_pm"
#define RSBAC_MS_ACI_LNETOBJ_NAME    "lnetobj_ms"
#define RSBAC_RC_ACI_LNETOBJ_NAME    "lnetobj_rc"
#define RSBAC_MAC_ACI_RNETOBJ_NAME   "rnetobj_mac"
#define RSBAC_FC_ACI_RNETOBJ_NAME    "rnetobj_fc"
#define RSBAC_SIM_ACI_RNETOBJ_NAME   "rnetobj_sim"
#define RSBAC_PM_ACI_RNETOBJ_NAME    "rnetobj_pm"
#define RSBAC_RC_ACI_RNETOBJ_NAME    "rnetobj_rc"

#define RSBAC_GEN_NETOBJ_ACI_VERSION 1
#define RSBAC_GEN_NETOBJ_ACI_KEY 1001
struct rsbac_gen_netobj_aci_t
    {
      rsbac_log_array_t           log_array_low;    /* nettemp/netobj based logging, */
      rsbac_log_array_t           log_array_high;   /* high and low bits */
    };
#define DEFAULT_GEN_NETOBJ_ACI \
    { \
      -1,                   /* log_array_low  (log request based) */ \
      -1                    /* log_array_high (log request based) */ \
    }

#if defined(CONFIG_RSBAC_MAC) || defined(CONFIG_RSBAC_MAC_MAINT)
#define RSBAC_MAC_NETOBJ_ACI_VERSION 1
#define RSBAC_MAC_NETOBJ_ACI_KEY 1001
struct rsbac_mac_netobj_aci_t
    {
      rsbac_security_level_t     sec_level; /* enum old_rsbac_security_level_t / __u8 */
      rsbac_mac_category_vector_t mac_categories;   /* MAC category set */
    };
#define DEFAULT_MAC_NETOBJ_ACI \
    { \
      SL_unclassified,  /* security_level (MAC) */ \
      RSBAC_MAC_DEF_CAT_VECTOR /* mac_categories (MAC) */ \
    }
#endif

#if defined(CONFIG_RSBAC_FC) || defined(CONFIG_RSBAC_FC_MAINT)
#define RSBAC_FC_NETOBJ_ACI_VERSION 1
#define RSBAC_FC_NETOBJ_ACI_KEY 1001
#endif

#if defined(CONFIG_RSBAC_SIM) || defined(CONFIG_RSBAC_SIM_MAINT)
#define RSBAC_SIM_NETOBJ_ACI_VERSION 1
#define RSBAC_SIM_NETOBJ_ACI_KEY 1001
#endif

#if defined(CONFIG_RSBAC_PM) || defined(CONFIG_RSBAC_PM_MAINT)
#define RSBAC_PM_NETOBJ_ACI_VERSION 1
#define RSBAC_PM_NETOBJ_ACI_KEY 1001
struct rsbac_pm_netobj_aci_t
    {
      rsbac_pm_object_class_id_t pm_object_class; /* netobj only */
      rsbac_pm_purpose_id_t      pm_ipc_purpose;
      rsbac_pm_object_type_int_t pm_object_type; /* enum rsbac_pm_object_type_t */
    };
#define DEFAULT_PM_NETOBJ_ACI \
    { \
      RSBAC_PM_IPC_OBJECT_CLASS_ID, /* pm_object_class_id (PM) */ \
      0,                /* pm_ipc_purpose  (PM) */ \
      PO_ipc            /* pm_object_type  (PM) */ \
    }
#endif

#if defined(CONFIG_RSBAC_MS) || defined(CONFIG_RSBAC_MS_MAINT)
#define RSBAC_MS_NETOBJ_ACI_VERSION 1
#define RSBAC_MS_NETOBJ_ACI_KEY 1001
struct rsbac_ms_netobj_aci_t
    {
             char                       ms_backbuf[RSBAC_MS_MAX_STR_LEN];
             int                        ms_buflen;
             int                        ms_str_nr[RSBAC_MS_NR_MALWARE];
             int                        ms_str_offset[RSBAC_MS_NR_MALWARE];
             rsbac_ms_scanned_t         ms_scanned;
    };
#define DEFAULT_MS_NETOBJ_ACI \
    { \
      ms_buflen:0,                /* ms_buflen */ \
      ms_str_nr:{0,0,0,0,0,0,0},  /* ms_str_nr */ \
      ms_str_offset:{0,0,0,0,0,0,0},  /* ms_offset */ \
      ms_scanned:MS_unscanned      /* ms_scanned */ \
    }
#endif

#if defined(CONFIG_RSBAC_RC) || defined(CONFIG_RSBAC_RC_MAINT)
#define RSBAC_RC_NETOBJ_ACI_VERSION 1
#define RSBAC_RC_NETOBJ_ACI_KEY 1001
#define RSBAC_RC_NETTEMP_ACI_VERSION 1
#define RSBAC_RC_NETTEMP_ACI_KEY 1002

struct rsbac_rc_nettemp_aci_t
    {
      rsbac_rc_type_id_t          netobj_type;    /* type inherited to netobj */
      rsbac_rc_type_id_t          nettemp_type;   /* type of this tenplate */
    };
#define DEFAULT_RC_NETTEMP_ACI \
    { \
      RSBAC_RC_GENERAL_TYPE, \
      RSBAC_RC_GENERAL_TYPE \
    }
#endif

#define RSBAC_NETTEMP_NR_ATTRIBUTES 11
#define RSBAC_NETTEMP_ATTR_LIST { \
      A_security_level, \
      A_mac_categories, \
      A_object_category, \
      A_data_type, \
      A_pm_object_class, \
      A_pm_ipc_purpose, \
      A_pm_object_type, \
      A_rc_type, \
      A_rc_type_nt, \
      A_log_array_low, \
      A_log_array_high \
      }

#define RSBAC_NETOBJ_NR_ATTRIBUTES 25
#define RSBAC_NETOBJ_ATTR_LIST { \
      A_local_sec_level, \
      A_remote_sec_level, \
      A_local_mac_categories, \
      A_remote_mac_categories, \
      A_local_object_category, \
      A_remote_object_category, \
      A_local_data_type, \
      A_remote_data_type, \
      A_local_pm_object_class, \
      A_remote_pm_object_class, \
      A_local_pm_ipc_purpose, \
      A_remote_pm_ipc_purpose, \
      A_local_pm_object_type, \
      A_remote_pm_object_type, \
      A_ms_backbuf, \
      A_ms_buflen, \
      A_ms_str_nr, \
      A_ms_str_offset, \
      A_ms_scanned, \
      A_local_rc_type, \
      A_remote_rc_type, \
      A_local_log_array_low, \
      A_remote_log_array_low, \
      A_local_log_array_high, \
      A_remote_log_array_high \
      }

#ifdef __KERNEL__
struct rsbac_nettemp_handles_t
    {
#if defined(CONFIG_RSBAC_IND_NETOBJ_LOG)
      rsbac_list_handle_t gen;
#endif
#if defined(CONFIG_RSBAC_MAC) || defined(CONFIG_RSBAC_MAC_MAINT)
      rsbac_list_handle_t mac;
#endif
#if defined(CONFIG_RSBAC_FC) || defined(CONFIG_RSBAC_FC_MAINT)
      rsbac_list_handle_t fc;
#endif
#if defined(CONFIG_RSBAC_SIM) || defined(CONFIG_RSBAC_SIM_MAINT)
      rsbac_list_handle_t sim;
#endif
#if defined(CONFIG_RSBAC_PM) || defined(CONFIG_RSBAC_PM_MAINT)
      rsbac_list_handle_t pm;
#endif
#if defined(CONFIG_RSBAC_RC) || defined(CONFIG_RSBAC_RC_MAINT)
      rsbac_list_handle_t rc;
#endif
    };

struct rsbac_lnetobj_handles_t
    {
#if defined(CONFIG_RSBAC_MAC) || defined(CONFIG_RSBAC_MAC_MAINT)
      rsbac_list_handle_t mac;
#endif
#if defined(CONFIG_RSBAC_FC) || defined(CONFIG_RSBAC_FC_MAINT)
      rsbac_list_handle_t fc;
#endif
#if defined(CONFIG_RSBAC_SIM) || defined(CONFIG_RSBAC_SIM_MAINT)
      rsbac_list_handle_t sim;
#endif
#if defined(CONFIG_RSBAC_PM) || defined(CONFIG_RSBAC_PM_MAINT)
      rsbac_list_handle_t pm;
#endif
#if defined(CONFIG_RSBAC_MS) || defined(CONFIG_RSBAC_MS_MAINT)
      rsbac_list_handle_t ms;
#endif
#if defined(CONFIG_RSBAC_RC) || defined(CONFIG_RSBAC_RC_MAINT)
      rsbac_list_handle_t rc;
#endif
    };
struct rsbac_rnetobj_handles_t
    {
#if defined(CONFIG_RSBAC_MAC) || defined(CONFIG_RSBAC_MAC_MAINT)
      rsbac_list_handle_t mac;
#endif
#if defined(CONFIG_RSBAC_FC) || defined(CONFIG_RSBAC_FC_MAINT)
      rsbac_list_handle_t fc;
#endif
#if defined(CONFIG_RSBAC_SIM) || defined(CONFIG_RSBAC_SIM_MAINT)
      rsbac_list_handle_t sim;
#endif
#if defined(CONFIG_RSBAC_PM) || defined(CONFIG_RSBAC_PM_MAINT)
      rsbac_list_handle_t pm;
#endif
#if defined(CONFIG_RSBAC_RC) || defined(CONFIG_RSBAC_RC_MAINT)
      rsbac_list_handle_t rc;
#endif
    };
#endif /* __KERNEL__ */


/**********************************************/
/*              Declarations                  */
/**********************************************/

#ifdef __KERNEL__
extern kdev_t rsbac_root_dev;

int rsbac_read_open (char *,
                     struct file  *,    /* file */
                     kdev_t);

int rsbac_write_open(char *,
                     struct file  *,    /* file */
                     kdev_t);

void rsbac_read_close(struct file *);

void rsbac_write_close(struct file *);

extern struct semaphore rsbac_write_sem;

/**********************************************/
/*              Locks                         */
/**********************************************/

extern inline void rsbac_read_lock(rwlock_t * lock_p, u_long * flags_p)
  {
    read_lock(lock_p);
  };

extern inline void rsbac_read_unlock(rwlock_t * lock_p, u_long * flags_p)
  {
    read_unlock(lock_p);
  };

extern inline void rsbac_write_lock(rwlock_t * lock_p, u_long * flags_p)
  {
    write_lock(lock_p);
  };

extern inline void rsbac_write_unlock(rwlock_t * lock_p, u_long * flags_p)
  {
    write_unlock(lock_p);
  };

#endif /* __KERNEL__ */

/**********************************************/
/*          External Declarations             */
/**********************************************/

#ifdef __KERNEL__

extern inline struct dentry *lock_parent(struct dentry *dentry);

#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,42)
extern inline struct dentry *unlock_dir(struct dentry *dentry);

extern inline void double_lock(struct dentry *d1, struct dentry *d2)
{
	struct semaphore *s1 = &d1->d_inode->i_sem;
	struct semaphore *s2 = &d2->d_inode->i_sem;

	if (s1 != s2) {
		if ((unsigned long) s1 < (unsigned long) s2) {
			struct semaphore *tmp = s2;
			s2 = s1; s1 = tmp;
		}
		down(s1);
	}
	down(s2);
}

extern inline void double_unlock(struct dentry *d1, struct dentry *d2)
{
	struct semaphore *s1 = &d1->d_inode->i_sem;
	struct semaphore *s2 = &d2->d_inode->i_sem;

	up(s1);
	if (s1 != s2)
		up(s2);
	dput(d1);
	dput(d2);
}
#endif

#endif /* __KERNEL__ */

#endif
