/************************************* */
/* Rule Set Based Access Control       */
/* Author and (c) 1999-2002:           */
/*   Amon Ott <ao@rsbac.org>           */
/* Helper functions for all parts      */
/* Last modified: 16/Oct/2002          */
/************************************* */

#include <rsbac/types.h>
#include <rsbac/getname.h>
#include <rsbac/helpers.h>
#include <rsbac/error.h>

#ifdef __KERNEL__
#include <linux/string.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
#include <rsbac/rkmem.h>
#include <rsbac/network.h>
#include <rsbac/net_getname.h>
#else
#include <string.h>
#include <errno.h>
#endif

static char  request_list[R_NONE+1][24] = {
                        "ADD_TO_KERNEL",
                        "ALTER",
                        "APPEND_OPEN",
                        "CHANGE_GROUP",
                        "CHANGE_OWNER",
                        "CHDIR",
                        "CLONE",
                        "CLOSE",
                        "CREATE",
                        "DELETE",
                        "EXECUTE",
                        "GET_PERMISSIONS_DATA",
                        "GET_STATUS_DATA",
                        "LINK_HARD",
                        "MODIFY_ACCESS_DATA",
                        "MODIFY_ATTRIBUTE",
                        "MODIFY_PERMISSIONS_DATA",
                        "MODIFY_SYSTEM_DATA",
                        "MOUNT",
                        "READ",
                        "READ_ATTRIBUTE",
                        "READ_WRITE_OPEN",
                        "READ_OPEN",
                        "REMOVE_FROM_KERNEL",
                        "RENAME",
                        "SEARCH",
                        "SEND_SIGNAL",
                        "SHUTDOWN",
                        "SWITCH_LOG",
                        "SWITCH_MODULE",
                        "TERMINATE",
                        "TRACE",
                        "TRUNCATE",
                        "UMOUNT",
                        "WRITE",
                        "WRITE_OPEN",
                        "MAP_EXEC",
                        "BIND",
                        "LISTEN",
                        "ACCEPT",
                        "CONNECT",
                        "SEND",
                        "RECEIVE",
                        "NET_SHUTDOWN",
                        "CHANGE_DAC_EFF_OWNER",
                        "CHANGE_DAC_FS_OWNER",
                        "NONE" };

static char  result_list[UNDEFINED+1][12] = {
                         "NOT_GRANTED",
                         "GRANTED",
                         "DO_NOT_CARE",
                         "UNDEFINED" };

static rsbac_switch_target_int_t  attr_mod_list[A_none+1] = {
                          GEN, /* pseudo */
                          MAC, /* security_level */
                          MAC, /* initial_security_level */
                          MAC, /* local_sec_level */
                          MAC, /* remote_sec_level */
                          MAC, /* min_security_level */
                          MAC, /* mac_categories */
                          MAC, /* mac_initial_categories */
                          MAC, /* local_mac_categories */
                          MAC, /* remote_mac_categories */
                          MAC, /* mac_min_categories */
                          MAC, /* mac_user_flags */
                          MAC, /* mac_process_flags */
                          MAC, /* mac_file_flags */
                          FC, /* object_category */
                          FC, /* local_object_category */
                          FC, /* remote_object_category */
                          SIM, /* data_type */
                          SIM, /* local_data_type */
                          SIM, /* local_data_type */
                          SW_NONE, /* system_role */
                          MAC, /* mac_role */
                          FC, /* fc_role */
                          SIM, /* sim_role */
                          MS, /* ms_role */
                          FF, /* ff_role */
                          AUTH, /* auth_role */
                          CAP, /* cap_role */
                          JAIL, /* jail_role */
                          MAC, /* current_sec_level */
                          MAC, /* mac_curr_categories */
                          MAC, /* min_write_open */
                          MAC, /* min_write_categories */
                          MAC, /* max_read_open */
                          MAC, /* max_read_categories */
                          MAC, /* mac_auto */
                          MAC, /* mac_trusted_for_user */
                          MAC, /* mac_check */
                          MAC, /* mac_prop_trusted */
                          PM, /* pm_role */
                          PM, /* pm_process_type */
                          PM, /* pm_current_task */
                          PM, /* pm_object_class */
                          PM, /* local_pm_object_class */
                          PM, /* remote_pm_object_class */
                          PM, /* pm_ipc_purpose */
                          PM, /* local_pm_ipc_purpose */
                          PM, /* remote_pm_ipc_purpose */
                          PM, /* pm_object_type */
                          PM, /* local_pm_object_type */
                          PM, /* remote_pm_object_type */
                          PM, /* pm_program_type */
                          PM, /* pm_tp */
                          PM, /* pm_task_set */
                          MS, /* ms_scanned */
                          MS, /* ms_trusted */
                          MS, /* ms_backbuf */
                          MS, /* ms_buflen */
                          MS, /* ms_str_nr */
                          MS, /* ms_str_offset */
                          MS, /* ms_sock_trusted_tcp */
                          MS, /* ms_sock_trusted_udp */
                          MS, /* ms_need_scan */
                          FF, /* ff_flags */
                          RC, /* rc_type */
                          RC, /* local_rc_type */
                          RC, /* remote_rc_type */
                          RC, /* rc_type_fd */
                          RC, /* rc_type_nt */
                          RC, /* rc_force_role */
                          RC, /* rc_initial_role */
                          RC, /* rc_role */
                          RC, /* rc_def_role */
                          AUTH, /* auth_may_setuid */
                          AUTH, /* auth_may_set_cap */
                          CAP, /* min_caps */
                          CAP, /* max_caps */
                          JAIL, /* jail_id */
                          JAIL, /* jail_ip */
                          JAIL, /* jail_flags */
                          RES, /* res_role */
                          RES, /* res_min */
                          RES, /* res_max */
                          GEN, /* log_array_low */
                          GEN, /* local_log_array_low */
                          GEN, /* remote_log_array_low */
                          GEN, /* log_array_high */
                          GEN, /* local_log_array_high */
                          GEN, /* remote_log_array_high */
                          GEN, /* log_program_based */
                          GEN, /* log_user_based */
                          GEN, /* symlink_add_uid */
                          GEN, /* symlink_add_mac_level */
                          GEN, /* symlink_add_rc_role */
                          GEN, /* linux_dac_disable */
                          CAP, /* cap_process_hiding */
#ifdef __KERNEL__
                          /* adf-request helpers */
                          SW_NONE, /* group */
                          SW_NONE, /* signal */
                          SW_NONE, /* mode */
                          SW_NONE, /* nlink */
                          SW_NONE, /* switch_target */
                          SW_NONE, /* mod_name */
                          SW_NONE, /* request */
                          SW_NONE, /* ms_segment */
                          SW_NONE, /* trace_request */
                          SW_NONE, /* auth_add_f_cap */
                          SW_NONE, /* auth_remove_f_cap */
                          SW_NONE, /* auth_get_caplist */
                          SW_NONE, /* prot_bits */
                          SW_NONE, /* internal */
                          SW_NONE, /* create_data */
                          SW_NONE, /* new_object */
                          SW_NONE, /* rlimit */
#endif
                          SW_NONE /* none */ };

static char  attribute_list[A_none+1][23] = {
                          "pseudo",
                          "security_level",
                          "initial_security_level",
                          "local_sec_level",
                          "remote_sec_level",
                          "min_security_level",
                          "mac_categories",
                          "mac_initial_categories",
                          "local_mac_categories",
                          "remote_mac_categories",
                          "mac_min_categories",
                          "mac_user_flags",
                          "mac_process_flags",
                          "mac_file_flags",
                          "object_category",
                          "local_object_category",
                          "remote_object_category",
                          "data_type",
                          "local_data_type",
                          "remote_data_type",
                          "system_role",
                          "mac_role",
                          "fc_role",
                          "sim_role",
                          "ms_role",
                          "ff_role",
                          "auth_role",
                          "cap_role",
                          "jail_role",
                          "current_sec_level",
                          "mac_curr_categories",
                          "min_write_open",
                          "min_write_categories",
                          "max_read_open",
                          "max_read_categories",
                          "mac_auto",
                          "mac_trusted_for_user",
                          "mac_check",
                          "mac_prop_trusted",
                          "pm_role",
                          "pm_process_type",
                          "pm_current_task",
                          "pm_object_class",
                          "local_pm_object_class",
                          "remote_pm_object_class",
                          "pm_ipc_purpose",
                          "local_pm_ipc_purpose",
                          "remote_pm_ipc_purpose",
                          "pm_object_type",
                          "local_pm_object_type",
                          "remote_pm_object_type",
                          "pm_program_type",
                          "pm_tp",
                          "pm_task_set",
                          "ms_scanned",
                          "ms_trusted",
                          "ms_backbuf",
                          "ms_buflen",
                          "ms_str_nr",
                          "ms_str_offset",
                          "ms_sock_trusted_tcp",
                          "ms_sock_trusted_udp",
                          "ms_need_scan",
                          "ff_flags",
                          "rc_type",
                          "local_rc_type",
                          "remote_rc_type",
                          "rc_type_fd",
                          "rc_type_nt",
                          "rc_force_role",
                          "rc_initial_role",
                          "rc_role",
                          "rc_def_role",
                          "auth_may_setuid",
                          "auth_may_set_cap",
                          "min_caps",
                          "max_caps",
                          "jail_id",
                          "jail_ip",
                          "jail_flags",
                          "res_role",
                          "res_min",
                          "res_max",
                          "log_array_low",
                          "local_log_array_low",
                          "remote_log_array_low",
                          "log_array_high",
                          "local_log_array_high",
                          "remote_log_array_high",
                          "log_program_based",
                          "log_user_based",
                          "symlink_add_uid",
                          "symlink_add_mac_level",
                          "symlink_add_rc_role",
                          "linux_dac_disable",
                          "cap_process_hiding",
#ifdef __KERNEL__
                          /* adf-request helpers */
                          "owner",
                          "group",
                          "signal",
                          "mode",
                          "nlink",
                          "switch_target",
                          "mod_name",
                          "request",
                          "ms_segment",
                          "trace_request",
                          "auth_add_f_cap",
                          "auth_remove_f_cap",
                          "auth_get_caplist",
                          "prot_bits",
                          "internal",
                          "create_data",
                          "new_object",
                          "rlimit",
#endif
                          "none" };

static char  target_list[T_NONE+1][11] = {
                          "FILE",
                          "DIR",
                          "FIFO",
                          "SYMLINK",
                          "DEV",
                          "IPC",
                          "SCD",
                          "USER",
                          "PROCESS",
                          "NETDEV",
                          "NETTEMP",
                          "NETOBJ",
                          "NETTEMP_NT",
#ifndef __KERNEL__
                          "FD",
#endif
                          "NONE" };

static char  ipc_target_list[I_none+1][7] = {
                          "sem",
                          "msg",
                          "shm",
                          "none" };

static char  switch_target_list[SW_NONE+1][12] = {
                          "GEN",
                          "MAC",
                          "FC",
                          "SIM",
                          "PM",
                          "MS",
                          "FF",
                          "RC",
                          "AUTH",
                          "REG",
                          "ACL",
                          "CAP",
                          "JAIL",
                          "RES",
                          "SOFTMODE",
                          "DAC_DISABLE",
                          "NONE" };

static char  error_list[RSBAC_EMAX][25] = {
                          "RSBAC_EPERM",
                          "RSBAC_EACCESS",
                          "RSBAC_EREADFAILED",
                          "RSBAC_EWRITEFAILED",
                          "RSBAC_EINVALIDPOINTER",
                          "RSBAC_ENOROOTDIR",
                          "RSBAC_EPATHTOOLONG",
                          "RSBAC_ENOROOTDEV",
                          "RSBAC_ENOTFOUND",
                          "RSBAC_ENOTINITIALIZED",
                          "RSBAC_EREINIT",
                          "RSBAC_ECOULDNOTADDDEVICE",
                          "RSBAC_ECOULDNOTADDITEM",
                          "RSBAC_ECOULDNOTCREATEPATH",
                          "RSBAC_EINVALIDATTR",
                          "RSBAC_EINVALIDDEV",
                          "RSBAC_EINVALIDTARGET",
                          "RSBAC_EINVALIDVALUE",
                          "RSBAC_EEXISTS",
                          "RSBAC_EINTERNONLY",
                          "RSBAC_EINVALIDREQUEST",
                          "RSBAC_ENOTWRITABLE",
                          "RSBAC_EMALWAREDETECTED",
                          "RSBAC_ENOMEM",
                          "RSBAC_EDECISIONMISMATCH",
                          "RSBAC_EINVALIDVERSION",
                          "RSBAC_EINVALIDMODULE"
                          };

static char scd_type_list[ST_none+1][12] = {
                          "time_strucs",
                          "clock",
                          "host_id",
                          "net_id",
                          "ioports",
                          "rlimit",
                          "swap",
                          "syslog",
                          "rsbac",
                          "rsbac_log",
                          "other",
                          "kmem",
                          "network",
                          "firewall",
                          "none" };

/* Attribute types */

#ifndef __KERNEL__
static char  attribute_param_list[A_none+1][193] = {
                          "user-pseudo (positive long integer)",
                          "0 = unclassified, 1 = confidential, 2 = secret,\n\t3 = top secret, 254 = inherit, max. level 252",
                          "0 = unclassified, 1 = confidential, 2 = secret,\n\t3 = top secret, 254 = inherit, max. level 252",
                          "0 = unclassified, 1 = confidential, 2 = secret,\n\t3 = top secret, 254 = inherit, max. level 252",
                          "0 = unclassified, 1 = confidential, 2 = secret,\n\t3 = top secret, 254 = inherit, max. level 252",
                          "0 = unclassified, 1 = confidential, 2 = secret,\n\t3 = top secret, 254 = inherit, max. level 252",
                          "Bit Set String of length 64 for all categories",
                          "Bit Set String of length 64 for all categories",
                          "Bit Set String of length 64 for all categories",
                          "Bit Set String of length 64 for all categories",
                          "Bit Set String of length 64 for all categories",
                          "1 = override, 4 = trusted, 8 = write_up, 16 = read_up,\n\t32 = write_down, 64 = allow_mac_auto",
                          "1 = override, 2 = auto, 4 = trusted, 8 = write_up,\n\t16 = read_up, 32 = write_down, 128 = prop_trusted",
                          "2 = auto, 4 = trusted, 8 = write_up, 16 = read_up,\n\t32 = write_down",
                          "0 = general, 1 = security, 2 = system, 3 = inherit",
                          "0 = general, 1 = security, 2 = system, 3 = inherit",
                          "0 = general, 1 = security, 2 = system, 3 = inherit",
                          "0 = none, 1 = SI, 2 = inherit",
                          "0 = none, 1 = SI, 2 = inherit",
                          "0 = none, 1 = SI, 2 = inherit",
                          "0 = user, 1 = security officer, 2 = administrator,\n\t3 = auditor",
                          "0 = user, 1 = security officer, 2 = administrator,\n\t3 = auditor",
                          "0 = user, 1 = security officer, 2 = administrator,\n\t3 = auditor",
                          "0 = user, 1 = security officer, 2 = administrator,\n\t3 = auditor",
                          "0 = user, 1 = security officer, 2 = administrator,\n\t3 = auditor",
                          "0 = user, 1 = security officer, 2 = administrator,\n\t3 = auditor",
                          "0 = user, 1 = security officer, 2 = administrator,\n\t3 = auditor",
                          "0 = user, 1 = security officer, 2 = administrator,\n\t3 = auditor",
                          "0 = user, 1 = security officer, 2 = administrator,\n\t3 = auditor",
                          "0 = unclassified, 1 = confidential, 2 = secret,\n\t3 = top secret, max. level 252",
                          "Bit Set String of length 64 for all categories",
                          "0 = unclassified, 1 = confidential, 2 = secret,\n\t3 = top secret, max. level 252",
                          "Bit Set String of length 64 for all categories",
                          "0 = unclassified, 1 = confidential, 2 = secret,\n\t3 = top secret, max. level 252",
                          "Bit Set String of length 64 for all categories",
                          "0 = no, 1 = yes, 2 = inherit (default value)",
                          "-3 = no user, -4 = all users, user-ID = for this user",
                          "0 = false, 1 = true",
                          "0 = false, 1 = true",
                          "0 = user, 1 = security officer, 2 = data protection officer,\n\t3 = TP-manager, 4 = system-admin",
                          "0 = none, 1 = TP",
                          "Task-ID (positive integer)",
                          "Class-ID (positive integer)",
                          "Class-ID (positive integer)",
                          "Class-ID (positive integer)",
                          "Purpose-ID (positive integer)",
                          "Purpose-ID (positive integer)",
                          "Purpose-ID (positive integer)",
                          "0 = none, 1 = TP, 2 = personal data, 3 = non-personal data,\n\t4 = ipc, 5 = dir",
                          "0 = none, 1 = TP, 2 = personal data, 3 = non-personal data,\n\t4 = ipc, 5 = dir",
                          "0 = none, 1 = TP, 2 = personal data, 3 = non-personal data,\n\t4 = ipc, 5 = dir",
                          "0 = none, 1 = TP",
                          "TP-ID (positive integer)",
                          "pm-task-list-ID (positive integer)",
                          "0 = unscanned, 1 = rejected, >=2 = accepted with level",
                          "0 = not_trusted, 1 = read trusted, 2 = full trusted",
                          "(internal only, do not set)",
                          "(internal only, do not set)",
                          "(internal only, do not set)",
                          "(internal only, do not set)",
                          "0 = not_trusted, 1 = active, 2 = full",
                          "0 = not_trusted, 1 = active, 2 = full",
                          "Bit-String for all Requests or list, I for inherit",
                          "1 = read_only, 2 = execute_only, 4 = search_only, 8 = write_only,\n\t16 = secure_delete, 32 = no_execute, 64 = no_delete_or_rename,\n\t128 = add_inherited (or'd), 256 = append_only, 512 = no_mount",
                          "RC-type-id",
                          "RC-type-id",
                          "RC-type-id",
                          "RC-type-id (-2 = inherit from parent)",
                          "RC-type-id",
                          "RC-role-id (-1 = inherit_user, -2 = inherit_process (keep),\n\t-3 = inherit_parent (def.),\n\t-4 = inherit_user_on_chown_only (root default)",
                          "RC-role-id (-3 = inherit_parent (default),\n\t-5 = use_force_role (root default)",
                          "RC-role-id",
                          "RC-role-id",
                          "0 = false, 1 = true",
                          "0 = false, 1 = true",
                          "Bit-Vector value or name list of desired caps",
                          "Bit-Vector value or name list of desired caps",
                          "JAIL ID (0 = off)",
                          "JAIL IP address a.b.c.d",
                          "JAIL flags (or'd, 1 = allow external IPC, 2 = allow all net families,\n\t4 = allow_rlimit, 8 = allow raw IP, 16 = auto adjust IP)",
                          "0 = user, 1 = security officer, 2 = administrator", /* res_role */
                          "array of non-negative integer values, all 0 for unset", /* res_min */
                          "array of non-negative integer values, all 0 for unset", /* res_max */
                          "Bit-String for all Requests, low bit",
                          "Bit-String for all Requests, low bit",
                          "Bit-String for all Requests, low bit",
                          "Bit-String for all Requests, high bit (l=0,h=0 = none, l=1,h=0 = denied,\n\tl=0,h=1 = full, l=1,h=1 = request based)",
                          "Bit-String for all Requests, high bit (l=0,h=0 = none, l=1,h=0 = denied,\n\tl=0,h=1 = full, l=1,h=1 = request based)",
                          "Bit-String for all Requests, high bit (l=0,h=0 = none, l=1,h=0 = denied,\n\tl=0,h=1 = full, l=1,h=1 = request based)",
                          "Bit-String for all Requests",
                          "Bit-String for all Requests",
                          "0 = false, 1 = true",
                          "0 = false, 1 = true",
                          "0 = false, 1 = true",
                          "0 = false, 1 = true, 2 = inherit (default)",
                          "0 = off (default), 1 = from other users, 2 = full",
                          "INVALID!" };
#endif

static char  log_level_list[LL_invalid+1][9] = {
                          "none",
                          "denied",
                          "full",
                          "request",
                          "invalid!" };

/*****************************************/

#ifdef __KERNEL__
#if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
EXPORT_SYMBOL(get_request_name);
#endif
#endif

char * get_request_name(char * request_name,
                        enum  rsbac_adf_request_t request)
  {
    if(!request_name)
      return(NULL);
    if(request >= R_NONE)
      strcpy(request_name, "ERROR!");
    else
      strcpy(request_name, request_list[request]);
    return(request_name);
  };

enum   rsbac_adf_request_t get_request_nr(const char * request_name)
  {
     enum  rsbac_adf_request_t i;
    
    if(!request_name)
      return(R_NONE);
    for (i = 0; i < R_NONE; i++)
      {
        if (!strcmp(request_name,request_list[i]))
          {
            return(i);
          }
      }
    return(R_NONE);
  };


char * get_result_name(char * res_name,
                       enum   rsbac_adf_req_ret_t res)
  {
    if(!res_name)
      return(NULL);
    if(res > UNDEFINED)
      strcpy(res_name, "ERROR!");
    else
      strcpy(res_name, result_list[res]);
    return(res_name);
  };

enum   rsbac_adf_req_ret_t get_result_nr(const char * res_name)
  {
     enum  rsbac_adf_req_ret_t i;
    
    if(!res_name)
      return(UNDEFINED);
    for (i = 0; i < UNDEFINED; i++)
      {
        if (!strcmp(res_name,result_list[i]))
          {
            return(i);
          }
      }
    return(UNDEFINED);
  };


#ifdef __KERNEL__
#if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
EXPORT_SYMBOL(get_attribute_name);
#endif
#endif

enum rsbac_switch_target_t get_attr_module(enum rsbac_attribute_t attr)
  {
    if(attr > A_none)
      return SW_NONE;
    else
      return attr_mod_list[attr];
  };

char * get_attribute_name(     char *            attr_name,
                          enum rsbac_attribute_t attr)
  {
    if(!attr_name)
      return(NULL);
    if(attr > A_none)
      strcpy(attr_name, "ERROR!");
    else
      strcpy(attr_name, attribute_list[attr]);
    return(attr_name);
  };

enum   rsbac_attribute_t get_attribute_nr(const char * attr_name)
  {
     enum  rsbac_attribute_t i;
    
    if(!attr_name)
      return(A_none);
    for (i = 0; i < A_none; i++)
      {
        if (!strcmp(attr_name,attribute_list[i]))
          {
            return(i);
          }
      }
    return(A_none);
  };


#ifdef __KERNEL__
#if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
EXPORT_SYMBOL(get_scd_type_name);
#endif
#endif

char * get_scd_type_name(char * res_name,
                         enum   rsbac_scd_type_t res)
  {
    if(!res_name)
      return(NULL);
    if(res > ST_none)
      strcpy(res_name, "ERROR!");
    else
      strcpy(res_name, scd_type_list[res]);
    return(res_name);
  };

enum   rsbac_scd_type_t get_scd_type_nr(const char * res_name)
  {
     enum  rsbac_scd_type_t i;
    
    if(!res_name)
      return(ST_none);
    for (i = 0; i < ST_none; i++)
      {
        if (!strcmp(res_name, scd_type_list[i]))
          {
            return(i);
          }
      }
    return(ST_none);
  };


#ifdef __KERNEL__
#if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
EXPORT_SYMBOL(get_target_name);
#endif
#endif

char * get_target_name(char * target_type_name,
                       enum   rsbac_target_t target,
                       char * target_id_name,
                       union  rsbac_target_id_t tid)
  {
#ifdef __KERNEL__
    char * help_name;
#else
    char help_name[RSBAC_MAXNAMELEN+4];
#endif

    if(!target_type_name)
      return(NULL);

#ifdef __KERNEL__
    #ifdef CONFIG_RSBAC_LOG_FULL_PATH
    help_name = rsbac_kmalloc(CONFIG_RSBAC_MAX_PATH_LEN + 4);
    #else
    help_name = rsbac_kmalloc(RSBAC_MAXNAMELEN + 4);
    #endif
    if(!help_name)
      return NULL;
#endif

    switch(target)
      {
#ifdef __KERNEL__
        case T_FD:      strcpy (target_type_name, "FD");
                        if(!target_id_name)
                          break;
                        sprintf(target_id_name, "Device %02u:%02u Inode %u",
                                MAJOR(tid.file.device), MINOR(tid.file.device),
                                tid.file.inode);
                        if(   tid.file.dentry_p
                           && tid.file.dentry_p->d_name.name
                           && tid.file.dentry_p->d_name.len
                          )
                          {
                            #ifdef CONFIG_RSBAC_LOG_FULL_PATH
                              if(rsbac_get_full_path(tid.file.dentry_p, help_name,
                                               CONFIG_RSBAC_MAX_PATH_LEN) > 0)
                                {
                                  strcat(target_id_name, " Path ");
                                  strcat(target_id_name, help_name);
                                }
                            #else
                              int namelen = rsbac_min(tid.file.dentry_p->d_name.len, RSBAC_MAXNAMELEN);

                              strcat(target_id_name, " Name ");
                              strncpy(help_name, tid.file.dentry_p->d_name.name, namelen);
                              help_name[namelen]=0;
                              strcat(target_id_name, help_name);
                            #endif
                          }
                        break;
        case T_FILE:    strcpy (target_type_name, "FILE");
                        if(!target_id_name)
                          break;
                        sprintf(target_id_name, "Device %02u:%02u Inode %u",
                                MAJOR(tid.file.device), MINOR(tid.file.device),
                                tid.file.inode);
                        if(   tid.file.dentry_p
                           && tid.file.dentry_p->d_name.name
                           && tid.file.dentry_p->d_name.len
                          )
                          {
                            #ifdef CONFIG_RSBAC_LOG_FULL_PATH
                              if(rsbac_get_full_path(tid.file.dentry_p, help_name,
                                               CONFIG_RSBAC_MAX_PATH_LEN) > 0)
                                {
                                  strcat(target_id_name, " Path ");
                                  strcat(target_id_name, help_name);
                                }
                            #else
                              int namelen = rsbac_min(tid.file.dentry_p->d_name.len, RSBAC_MAXNAMELEN);

                              strcat(target_id_name, " Name ");
                              strncpy(help_name, tid.file.dentry_p->d_name.name, namelen);
                              help_name[namelen]=0;
                              strcat(target_id_name, help_name);
                            #endif
                          }
                        break;
        case T_DIR:     strcpy (target_type_name, "DIR");
                        if(!target_id_name)
                          break;
                        sprintf(target_id_name, "Device %02u:%02u Inode %u",
                                MAJOR(tid.dir.device), MINOR(tid.dir.device),
                                tid.dir.inode);
                        if(   tid.dir.dentry_p
                           && tid.dir.dentry_p->d_name.name
                           && tid.dir.dentry_p->d_name.len
                          )
                          {
                            #ifdef CONFIG_RSBAC_LOG_FULL_PATH
                              if(rsbac_get_full_path(tid.dir.dentry_p, help_name,
                                               CONFIG_RSBAC_MAX_PATH_LEN) > 0)
                                {
                                  strcat(target_id_name, " Path ");
                                  strcat(target_id_name, help_name);
                                }
                            #else
                              int namelen = rsbac_min(tid.dir.dentry_p->d_name.len, RSBAC_MAXNAMELEN);

                              strcat(target_id_name, " Name ");
                              strncpy(help_name, tid.dir.dentry_p->d_name.name, namelen);
                              help_name[namelen]=0;
                              strcat(target_id_name, help_name);
                            #endif
                          }
                        break;
        case T_FIFO:    strcpy (target_type_name, "FIFO");
                        if(!target_id_name)
                          break;
                        sprintf(target_id_name, "Device %02u:%02u Inode %u",
                                MAJOR(tid.fifo.device), MINOR(tid.fifo.device),
                                tid.fifo.inode);
                        if(   tid.fifo.dentry_p
                           && tid.fifo.dentry_p->d_name.name
                           && tid.fifo.dentry_p->d_name.len
                          )
                          {
                            #ifdef CONFIG_RSBAC_LOG_FULL_PATH
                              if(rsbac_get_full_path(tid.fifo.dentry_p, help_name,
                                               CONFIG_RSBAC_MAX_PATH_LEN) > 0)
                                {
                                  strcat(target_id_name, " Path ");
                                  strcat(target_id_name, help_name);
                                }
                            #else
                              int namelen = rsbac_min(tid.fifo.dentry_p->d_name.len, RSBAC_MAXNAMELEN);

                              strcat(target_id_name, " Name ");
                              strncpy(help_name, tid.fifo.dentry_p->d_name.name, namelen);
                              help_name[namelen]=0;
                              strcat(target_id_name, help_name);
                            #endif
                          }
                        break;
        case T_SYMLINK: strcpy (target_type_name, "SYMLINK");
                        if(!target_id_name)
                          break;
                        sprintf(target_id_name, "Device %02u:%02u Inode %u",
                                MAJOR(tid.symlink.device), MINOR(tid.symlink.device),
                                tid.symlink.inode);
                        if(   tid.symlink.dentry_p
                           && tid.symlink.dentry_p->d_name.name
                           && tid.symlink.dentry_p->d_name.len
                          )
                          {
                            #ifdef CONFIG_RSBAC_LOG_FULL_PATH
                              if(rsbac_get_full_path(tid.symlink.dentry_p, help_name,
                                               CONFIG_RSBAC_MAX_PATH_LEN) > 0)
                                {
                                  strcat(target_id_name, " Path ");
                                  strcat(target_id_name, help_name);
                                }
                            #else
                              int namelen = rsbac_min(tid.symlink.dentry_p->d_name.len, RSBAC_MAXNAMELEN);

                              strcat(target_id_name, " Name ");
                              strncpy(help_name, tid.symlink.dentry_p->d_name.name, namelen);
                              help_name[namelen]=0;
                              strcat(target_id_name, help_name);
                            #endif
                          }
                        break;
        case T_DEV:     strcpy (target_type_name, "DEV");
                        if(!target_id_name)
                          break;
                        if(tid.dev.type == D_block)
                          sprintf(target_id_name, "block %02u:%02u",
                                  MAJOR(tid.dev.id), MINOR(tid.dev.id));
                        else
                          sprintf(target_id_name, "char %02u:%02u",
                                  MAJOR(tid.dev.id), MINOR(tid.dev.id));
                        break;
        case T_NETOBJ:  strcpy (target_type_name, "NETOBJ");
                        if(!target_id_name)
                          break;
                        if(   tid.netobj.sock_p
                           && tid.netobj.sock_p->ops
                           && tid.netobj.sock_p->sk
                          )
                          {
                            char type_name[RSBAC_MAXNAMELEN];

                            switch(tid.netobj.sock_p->ops->family)
                              {
                                case AF_INET:
                                  {
                                    __u32 saddr;
                                    __u16 sport;
                                    __u32 daddr;
                                    __u16 dport;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
                                    struct net_device *dev;
#else
                                    struct device *dev;
#endif
                                    char ldevname[RSBAC_IFNAMSIZ+10];
                                    char rdevname[RSBAC_IFNAMSIZ+10];

                                    if(tid.netobj.local_addr)
                                      {
                                        struct sockaddr_in * addr = tid.netobj.local_addr;

                                        saddr = addr->sin_addr.s_addr;
                                        sport = ntohs(addr->sin_port);
                                      }
                                    else
                                      {
                                        saddr = tid.netobj.sock_p->sk->saddr;
                                        sport = tid.netobj.sock_p->sk->num;
                                      }
                                    if(tid.netobj.remote_addr)
                                      {
                                        struct sockaddr_in * addr = tid.netobj.remote_addr;

                                        daddr = addr->sin_addr.s_addr;
                                        dport = ntohs(addr->sin_port);
                                      }
                                    else
                                      {
                                        daddr = tid.netobj.sock_p->sk->daddr;
                                        dport = ntohs(tid.netobj.sock_p->sk->dport);
                                      }
                                    dev = ip_dev_find(saddr);
                                    if(dev)
                                      {
                                        sprintf(ldevname, "%s:", dev->name);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
                                        dev_put(dev);
#endif
                                      }
                                    else
                                      ldevname[0] = 0;
                                    dev = ip_dev_find(daddr);
                                    if(dev)
                                      {
                                        sprintf(rdevname, "%s:", dev->name);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
                                        dev_put(dev);
#endif
                                      }
                                    else
                                      rdevname[0] = 0;
                                    sprintf(target_id_name, "%p INET %s proto %s local %s%u.%u.%u.%u:%u remote %s%u.%u.%u.%u:%u",
                                            tid.netobj.sock_p,
                                            rsbac_get_net_type_name(type_name,
                                                                    tid.netobj.sock_p->type),
                                            rsbac_get_net_protocol_name(help_name,
                                                                        tid.netobj.sock_p->sk->protocol),
                                            ldevname,
                                            NIPQUAD(saddr),
                                            sport,
                                            rdevname,
                                            NIPQUAD(daddr),
                                            dport);
                                  }
                                  break;
                                case AF_UNIX:
                                  if(tid.netobj.sock_p->sk->protinfo.af_unix.addr)
                                    sprintf(target_id_name, "%p UNIX %s %s",
                                            tid.netobj.sock_p,
                                            rsbac_get_net_type_name(type_name,
                                                                    tid.netobj.sock_p->type),
                                            tid.netobj.sock_p->sk->protinfo.af_unix.addr->name[0].sun_path);
                                  else
                                  if(tid.netobj.local_addr)
                                    {
                                      struct sockaddr_un * addr = tid.netobj.local_addr;

                                      sprintf(target_id_name, "%p UNIX %s %s",
                                              tid.netobj.sock_p,
                                              rsbac_get_net_type_name(type_name,
                                                                      tid.netobj.sock_p->type),
                                              addr->sun_path);
                                    }
                                  else
                                    sprintf(target_id_name, "%p UNIX %s",
                                            tid.netobj.sock_p,
                                            rsbac_get_net_type_name(type_name,
                                                                    tid.netobj.sock_p->type));
                                  break;
                                default:
                                  sprintf(target_id_name, "%p %s %s",
                                          tid.netobj.sock_p,
                                          rsbac_get_net_family_name(help_name,
                                                                    tid.netobj.sock_p->ops->family),
                                          rsbac_get_net_type_name(type_name,
                                                                  tid.netobj.sock_p->type));
                              }
                          }
                        else
                          {
                            sprintf(target_id_name, "%p", tid.netobj.sock_p);
                          }
                        break;
#endif /* __KERNEL__ */
        case T_IPC:     strcpy (target_type_name, "IPC");
                        if(!target_id_name)
                          break;
                        switch (tid.ipc.type)
                          {
                            case I_sem: strcpy(target_id_name, "Sem-ID ");
                                        break;
                            case I_msg: strcpy(target_id_name, "Msg-ID ");
                                        break;
                            case I_shm: strcpy(target_id_name, "Shm-ID ");
                                        break;
                            default:    strcpy(target_id_name, "???-ID ");
                                        break;
                          };
                        ulongtostr(help_name, tid.ipc.id.id_nr);
                        strcat(target_id_name, help_name);
                        break;
        case T_SCD:     strcpy (target_type_name, "SCD");
                        if(!target_id_name)
                          break;
                        get_scd_type_name(target_id_name, tid.scd);
                        break;
        case T_USER:    strcpy (target_type_name, "USER");
                        if(!target_id_name)
                          break;
                        inttostr(target_id_name, tid.user);
                        break;
        case T_PROCESS: strcpy (target_type_name, "PROCESS");
                        if(!target_id_name)
                          break;
                        ulongtostr(target_id_name, tid.process);
                        break;
        case T_NETDEV:  strcpy (target_type_name, "NETDEV");
                        if(!target_id_name)
                          break;
                        strncpy(target_id_name, tid.netdev, RSBAC_IFNAMSIZ);
                        target_id_name[RSBAC_IFNAMSIZ] = 0;
                        break;
        case T_NETTEMP: strcpy (target_type_name, "NETTEMP");
                        if(!target_id_name)
                          break;
                        sprintf(target_id_name, "%u", tid.nettemp);
                        break;
        case T_NETTEMP_NT: strcpy (target_type_name, "NETTEMP_NT");
                        if(!target_id_name)
                          break;
                        sprintf(target_id_name, "%u", tid.nettemp);
                        break;
        case T_NONE:    strcpy (target_type_name, "NONE");
                        if(!target_id_name)
                          break;
                        strcpy (target_id_name, "NONE");
                        break;
        default:        strcpy (target_type_name, "ERROR!!!");
                        if(!target_id_name)
                          break;
                        strcpy (target_id_name, "ERROR!!!");
      };
#ifdef __KERNEL__
    rsbac_kfree(help_name);
#endif
    return(target_type_name);
  };

#ifndef __KERNEL__
char * get_target_name_only(char * target_type_name,
                            enum   rsbac_target_t target)
  {
    if(!target_type_name)
      return(NULL);

    switch(target)
      {
        case T_FILE:    strcpy (target_type_name, "FILE");
                        break;
        case T_DIR:     strcpy (target_type_name, "DIR");
                        break;
        case T_FIFO:    strcpy (target_type_name, "FIFO");
                        break;
        case T_SYMLINK: strcpy (target_type_name, "SYMLINK");
                        break;
        case T_DEV:     strcpy (target_type_name, "DEV");
                        break;
        case T_NETOBJ:  strcpy (target_type_name, "NETOBJ");
                        break;
        case T_IPC:     strcpy (target_type_name, "IPC");
                        break;
        case T_SCD:     strcpy (target_type_name, "SCD");
                        break;
        case T_USER:    strcpy (target_type_name, "USER");
                        break;
        case T_PROCESS: strcpy (target_type_name, "PROCESS");
                        break;
        case T_NETDEV:  strcpy (target_type_name, "NETDEV");
                        break;
        case T_NETTEMP: strcpy (target_type_name, "NETTEMP");
                        break;
        case T_NETTEMP_NT: strcpy (target_type_name, "NETTEMP_NT");
                        break;
        case T_NONE:    strcpy (target_type_name, "NONE");
                        break;
        default:        strcpy (target_type_name, "ERROR!!!");
      };
    return(target_type_name);
  };
#endif

enum   rsbac_target_t get_target_nr(const char * target_name)
  {
     enum  rsbac_target_t i;
    
    if(!target_name)
      return(T_NONE);
    for (i = 0; i < T_NONE; i++)
      {
        if (!strcmp(target_name,target_list[i]))
          {
            return(i);
          }
      }
    return(T_NONE);
  };

char * get_ipc_target_name(char * ipc_name,
                        enum  rsbac_ipc_type_t target)
  {
    if(!ipc_name)
      return(NULL);
    if(target > I_none)
      strcpy(ipc_name, "ERROR!");
    else
      strcpy(ipc_name, ipc_target_list[target]);
    return(ipc_name);
  };

enum   rsbac_ipc_type_t get_ipc_target_nr(const char * ipc_name)
  {
     enum  rsbac_ipc_type_t i;
    
    if(!ipc_name)
      return(I_none);
    for (i = 0; i < I_none; i++)
      {
        if (!strcmp(ipc_name,ipc_target_list[i]))
          {
            return(i);
          }
      }
    return(I_none);
  };


#ifdef __KERNEL__
#if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
EXPORT_SYMBOL(get_switch_target_name);
#endif
#endif

char * get_switch_target_name(char * switch_name,
                        enum  rsbac_switch_target_t target)
  {
    if(!switch_name)
      return(NULL);
    if(target > SW_NONE)
      strcpy(switch_name, "ERROR!");
    else
      strcpy(switch_name, switch_target_list[target]);
    return(switch_name);
  };

enum   rsbac_switch_target_t get_switch_target_nr(const char * switch_name)
  {
     enum  rsbac_switch_target_t i;
    
    if(!switch_name)
      return(SW_NONE);
    for (i = 0; i < SW_NONE; i++)
      {
#ifdef __KERNEL__
        if (!strncmp(switch_name,switch_target_list[i],strlen(switch_target_list[i])))
#else
        if (!strcmp(switch_name,switch_target_list[i]))
#endif
          {
            return(i);
          }
      }
    return(SW_NONE);
  };


#ifdef __KERNEL__
#if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
EXPORT_SYMBOL(get_error_name);
#endif
#endif

char * get_error_name(char * error_name,
                      int error)
  {
    if(!error_name)
      return(NULL);
    if(RSBAC_ERROR(error))
      strcpy(error_name, error_list[(-error)-RSBAC_EPERM]);
    else
      #ifdef __KERNEL__ 
      inttostr(error_name, error);
      #else
      strcpy(error_name, strerror(errno));
      #endif
    return(error_name);
  };

#ifndef __KERNEL__
char * get_attribute_param(     char *            attr_name,
                          enum rsbac_attribute_t attr)
  {
    if(!attr_name)
      return(NULL);
    if(attr > A_none)
      strcpy(attr_name, "ERROR!");
    else
      strcpy(attr_name, attribute_param_list[attr]);
    return(attr_name);
  };
#endif

char * get_log_level_name(char * ll_name,
                        enum  rsbac_log_level_t target)
  {
    if(!ll_name)
      return(NULL);
    if(target > LL_invalid)
      strcpy(ll_name, "ERROR!");
    else
      strcpy(ll_name, log_level_list[target]);
    return(ll_name);
  };

enum   rsbac_log_level_t get_log_level_nr(const char * ll_name)
  {
     enum  rsbac_log_level_t i;
    
    if(!ll_name)
      return(LL_invalid);
    for (i = 0; i < LL_invalid; i++)
      {
        if (!strcmp(ll_name,log_level_list[i]))
          {
            return(i);
          }
      }
    return(LL_invalid);
  };

