/************************************* */
/* Rule Set Based Access Control       */
/* Author and (c) 1999-2002:           */
/*   Amon Ott <ao@rsbac.org>           */
/* Helper functions for all parts      */
/* Last modified: 22/Apr/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>
#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",
                        "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, /* local_sec_level */
                          MAC, /* remote_sec_level */
                          MAC, /* mac_categories */
                          MAC, /* local_mac_categories */
                          MAC, /* remote_mac_categories */
                          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 */
                          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 */
                          MAC, /* mac_trusted_for_user */
                          MAC, /* mac_check */
                          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 */
                          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 */
                          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_rc_role */
                          GEN, /* linux_dac_disable */
#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 */
    #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
                          SW_NONE, /* create_data */
    #endif
#endif
                          SW_NONE /* none */ };

static char  attribute_list[A_none+1][23] = {
                          "pseudo",
                          "security_level",
                          "local_sec_level",
                          "remote_sec_level",
                          "mac_categories",
                          "local_mac_categories",
                          "remote_mac_categories",
                          "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",
                          "current_sec_level",
                          "mac_curr_categories",
                          "min_write_open",
                          "min_write_categories",
                          "max_read_open",
                          "max_read_categories",
                          "mac_auto",
                          "mac_trusted",
                          "mac_trusted_for_user",
                          "mac_check",
                          "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",
                          "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",
                          "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_rc_role",
                          "linux_dac_disable",
#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",
    #if defined(CONFIG_RSBAC_REG) || defined(CONFIG_RSBAC_REG_MAINT)
                          "create_data",
    #endif
#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",
                          "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][181] = {
                          "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",
                          "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",
                          "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",
                          "0 = user, 1 = security officer, 2 = administrator",
                          "0 = user, 1 = security officer, 2 = administrator",
                          "0 = user, 1 = security officer, 2 = administrator",
                          "0 = user, 1 = security officer, 2 = administrator",
                          "0 = user, 1 = security officer, 2 = administrator",
                          "0 = user, 1 = security officer, 2 = administrator",
                          "0 = user, 1 = security officer, 2 = administrator",
                          "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 = false, 1 = true",
                          "0 = false, 1 = true",
                          "-3 = no user, -4 = all users, user-ID = for this user",
                          "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",
                          "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",
                          "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",
                          "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, 2 = inherit (default)",
                          "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_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 = 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);
  };

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(-error));
      #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);
  };

