/*************************************************** */
/* Rule Set Based Access Control                     */
/* Implementation of the Access Control Decision     */
/* Facility (ADF) - Functional Control               */
/* File: rsbac/adf/fc/main.c                         */
/*                                                   */
/* Author and (c) 1999-2003: Amon Ott <ao@rsbac.org> */
/*                                                   */
/* Last modified: 06/Jun/2003                        */
/*************************************************** */

#include <linux/string.h>
#include <rsbac/aci.h>
#include <rsbac/adf_main.h>
#include <rsbac/error.h>
#include <rsbac/helpers.h>
#include <rsbac/getname.h>
#include <rsbac/network.h>

/************************************************* */
/*           Global Variables                      */
/************************************************* */

/************************************************* */
/*          Internal Help functions                */
/************************************************* */

static enum rsbac_adf_req_ret_t
         check_role_fc(   enum  rsbac_target_t          target,
                          union rsbac_target_id_t       tid,
                                rsbac_uid_t             owner)
  {
    int                           err;
    union rsbac_target_id_t       i_tid;
    union rsbac_attribute_value_t i_attr_val1;
    union rsbac_attribute_value_t i_attr_val2;

    /* test object's object_category */
    if ((err=rsbac_get_attr(FC,
                            target,
                            tid,
                            A_object_category,
                            &i_attr_val1,
                            TRUE)))
      {
        printk(KERN_WARNING "check_role_fc(): rsbac_get_attr() returned error %i!\n",err);
        return(NOT_GRANTED);
      }
    /* Access to category general is always granted */
    if (i_attr_val1.object_category == OC_general)
      return(GRANTED);

    /* test owner's fc_role */
    i_tid.user = owner;
    if ((err=rsbac_get_attr(FC,
                            T_USER,
                       i_tid,
                       A_fc_role,
                       &i_attr_val2,
                       TRUE)))
      {
        printk(KERN_WARNING "check_role_fc(): rsbac_get_attr() returned error %i!\n",err);
        return(NOT_GRANTED);
      }

    /* Access is granted, if object_category and fc_role fit */

    if (    (   (i_attr_val1.object_category == OC_system)
             && (i_attr_val2.system_role == SR_administrator)
            )
         || (   (i_attr_val1.object_category == OC_security)
             && (i_attr_val2.system_role == SR_security_officer)
            )
       )
      return(GRANTED);
    else
      {
/*        printk(KERN_DEBUG "check_role_fc(): role is %i, obj_cat is %i -> NOT_GRANTED!\n",
               i_attr_val2.system_role, i_attr_val1.object_category); */
        return(NOT_GRANTED);
      }
  }

#ifdef CONFIG_RSBAC_FC_NET_OBJ_PROT
static enum rsbac_adf_req_ret_t
         check_role_fc_netobj(enum  rsbac_adf_request_t     request,
                              union rsbac_target_id_t       tid,
                                    rsbac_uid_t             owner)
  {
    int                           err;
    union rsbac_target_id_t       i_tid;
    enum  rsbac_attribute_t       i_attr;
    union rsbac_attribute_value_t i_attr_val1;
    union rsbac_attribute_value_t i_attr_val2;

    if(rsbac_net_remote_request(request))
      i_attr = A_remote_object_category;
    else
      i_attr = A_local_object_category;
    /* test object's object_category */
    if ((err=rsbac_get_attr(FC,
                            T_NETOBJ,
                            tid,
                            i_attr,
                            &i_attr_val1,
                            TRUE)))
      {
        printk(KERN_WARNING "check_role_fc_netobj(): rsbac_get_attr() returned error %i!\n",err);
        return(NOT_GRANTED);
      }
    /* Access to category general is always granted */
    if (i_attr_val1.object_category == OC_general)
      return(GRANTED);

    /* test owner's fc_role */
    i_tid.user = owner;
    if ((err=rsbac_get_attr(FC,
                            T_USER,
                       i_tid,
                       A_fc_role,
                       &i_attr_val2,
                       TRUE)))
      {
        printk(KERN_WARNING "check_role_fc_netobj(): rsbac_get_attr() returned error %i!\n",err);
        return(NOT_GRANTED);
      }

    /* Access is granted, if object_category and fc_role fit */

    if (    (   (i_attr_val1.object_category == OC_system)
             && (i_attr_val2.system_role == SR_administrator)
            )
         || (   (i_attr_val1.object_category == OC_security)
             && (i_attr_val2.system_role == SR_security_officer)
            )
       )
      return(GRANTED);
    else
      {
/*        printk(KERN_DEBUG "check_role_fc_netobj(): role is %i, obj_cat is %i -> NOT_GRANTED!\n",
               i_attr_val2.system_role, i_attr_val1.object_category); */
        return(NOT_GRANTED);
      }
  }
#endif

static enum rsbac_adf_req_ret_t
  fc_check_sysrole(rsbac_uid_t owner, enum rsbac_system_role_t role)
  {
    union rsbac_target_id_t i_tid;
    union rsbac_attribute_value_t i_attr_val1;

    i_tid.user = owner;
    if (rsbac_get_attr(FC,
                       T_USER,
                       i_tid,
                       A_fc_role,
                       &i_attr_val1,
                       TRUE))
      {
        printk(KERN_WARNING
               "fc_check_sysrole(): rsbac_get_attr() returned error!\n");
               return(NOT_GRANTED);
      }
    /* if correct role, then grant */
    if (i_attr_val1.system_role == role)
      return(GRANTED);
    else
      return(NOT_GRANTED);
  }


/************************************************* */
/*          Externally visible functions           */
/************************************************* */

enum rsbac_adf_req_ret_t
   rsbac_adf_request_fc  (enum  rsbac_adf_request_t     request,
                                rsbac_pid_t             caller_pid,
                          enum  rsbac_target_t          target,
                          union rsbac_target_id_t       tid,
                          enum  rsbac_attribute_t       attr,
                          union rsbac_attribute_value_t attr_val,
                                rsbac_uid_t             owner)
  {
    int                           err;
    enum  rsbac_adf_req_ret_t result = DO_NOT_CARE;
    union rsbac_target_id_t       i_tid;
    union rsbac_attribute_value_t i_attr_val1;
#ifdef CONFIG_RSBAC_FC_ROLE_PROT
    union rsbac_attribute_value_t i_attr_val2;
#endif

    switch (request)
      {
        case R_ADD_TO_KERNEL:
            switch(target)
              {
                case T_NONE:
                  /* test owner's fc_role */
                  return fc_check_sysrole(owner, SR_administrator);

                /* all other cases are unknown */
                default:
                  return(DO_NOT_CARE);
              }

        case R_ALTER:
            /* only for IPC */
            switch(target)
              {
                case T_IPC:
                  return(check_role_fc(target,tid,owner));

                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
             }

        case R_APPEND_OPEN:
        case R_READ_WRITE_OPEN:
            switch(target)
              {
                case T_FILE:
                case T_DEV:
                case T_FIFO:
                case T_IPC:
                  return(check_role_fc(target,tid,owner));

                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }

        case R_CHANGE_GROUP:
            switch(target)
              {
                case T_FILE:
                case T_DIR:
                case T_FIFO:
                case T_SYMLINK:
                case T_IPC:
                  return(check_role_fc(target,tid,owner));

                case T_PROCESS:
                case T_USER:
                  return(DO_NOT_CARE);
                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }

        case R_CHANGE_OWNER:
            switch(target)
              {
                case T_FILE:
                case T_DIR:
                case T_FIFO:
                case T_SYMLINK:
                case T_IPC:
                  return(check_role_fc(target,tid,owner));
                  
                case T_PROCESS:
                  #ifdef CONFIG_RSBAC_FC_ROLE_PROT
                  if(attr != A_owner)
                    return(UNDEFINED);
                  /* Administrator or secoff? */
                  i_tid.user = owner;
                  if (rsbac_get_attr(FC,
                                     T_USER,
                                     i_tid,
                                     A_fc_role,
                                     &i_attr_val1,
                                     TRUE))
                    {
                      printk(KERN_WARNING
                             "rsbac_adf_request_fc(): rsbac_get_attr() returned error!\n");
                      return(NOT_GRANTED);
                    }
                  /* if general user, then grant */
                  if (i_attr_val1.system_role == SR_user)
                    return(GRANTED);
                  /* get target user's role */
                  i_tid.user = attr_val.owner;
                  if (rsbac_get_attr(FC,
                                     T_USER,
                                     i_tid,
                                     A_fc_role,
                                     &i_attr_val2,
                                     TRUE))
                    {
                      printk(KERN_WARNING
                             "rsbac_adf_request_fc(): rsbac_get_attr() returned error!\n");
                      return(NOT_GRANTED);
                    }
                  /* target is no general user and has different role -> deny */
                  if (   (i_attr_val2.system_role != SR_user)
                      && (i_attr_val1.system_role != i_attr_val2.system_role)
                     )
                    return(NOT_GRANTED);
                  else
                    return(GRANTED);
                  #endif

                  /* fall through... */
                case T_NONE:
                  return(DO_NOT_CARE);
                /* all other cases are unknown */
                default:
                  return(DO_NOT_CARE);
              }

        case R_CHDIR:
            switch(target)
              {
                case T_DIR: 
                  return(check_role_fc(target,tid,owner));

                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }

        case R_CLONE:
        case R_TRACE:
        case R_SEND_SIGNAL:
        case R_TERMINATE:
            if (target == T_PROCESS)
              return(DO_NOT_CARE);
            else
              return(DO_NOT_CARE);

        /* Creating dir or (pseudo) file IN target dir! */
        case R_CREATE:
            switch(target)
              {
                case T_DIR: 
                  return(check_role_fc(target,tid,owner));
                /* IPC is always granted */
                case T_IPC:
                  return(GRANTED);

#ifdef CONFIG_RSBAC_FC_NET_OBJ_PROT
                case T_NETTEMP:
                  return fc_check_sysrole(owner, SR_security_officer);

                case T_NETOBJ:
                  return(check_role_fc_netobj(request,tid,owner));
#endif

                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }

        case R_DELETE:
            switch(target)
              {
                case T_FILE:
                case T_DIR:
                case T_FIFO:
                case T_SYMLINK:
                case T_IPC:
                  return(check_role_fc(target,tid,owner));

#ifdef CONFIG_RSBAC_FC_NET_OBJ_PROT
                case T_NETTEMP:
                  return fc_check_sysrole(owner, SR_security_officer);
#endif
                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }

        case R_EXECUTE:
            switch(target)
              {
                case T_FILE:
                  return(check_role_fc(target,tid,owner));

                /* all other cases are unknown */
                default:
                  return(DO_NOT_CARE);
              }

        case R_GET_STATUS_DATA:
            switch(target)
              {
                case T_SCD:
                  /* target rsbaclog? only for secoff */
                  if (tid.scd != ST_rsbaclog)
                    return(GRANTED);
                  /* Secoff or auditor? */
                  if(fc_check_sysrole(owner, SR_security_officer) == NOT_GRANTED)
                    return fc_check_sysrole(owner, SR_auditor);
                  else
                    return GRANTED;
                default:
                  return(DO_NOT_CARE);
               };

        case R_LINK_HARD:
            switch(target)
              {
                case T_FILE:
                case T_FIFO:
                case T_SYMLINK:
                  return(check_role_fc(target,tid,owner));

                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }

        case R_MODIFY_ACCESS_DATA:
        case R_RENAME:
            switch(target)
              {
                case T_FILE:
                case T_DIR:
                case T_FIFO:
                case T_SYMLINK:
                  return(check_role_fc(target,tid,owner));

                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }

        case R_MODIFY_ATTRIBUTE:
            switch(attr)
              {
                case A_system_role:
                case A_fc_role:
                case A_object_category:
                case A_local_object_category:
                case A_remote_object_category:
                #ifdef CONFIG_RSBAC_FC_GEN_PROT
                case A_log_array_low:
                case A_log_array_high:
                case A_log_program_based:
                case A_log_user_based:
                case A_symlink_add_uid:
                case A_symlink_add_rc_role:
                case A_linux_dac_disable:
                #endif
                #ifdef CONFIG_RSBAC_FC_AUTH_PROT
                case A_auth_may_setuid:
                case A_auth_may_set_cap:
                case A_auth_add_f_cap:
                case A_auth_remove_f_cap:
                #endif
                /* All attributes (remove target!) */
                case A_none:
                  /* Security Officer? */
                  return fc_check_sysrole(owner, SR_security_officer);

                default:
                  return(DO_NOT_CARE);
              }

        case R_MODIFY_PERMISSIONS_DATA:
            switch(target)
              {
                case T_FILE:
                case T_DIR:
                case T_FIFO:
                case T_SYMLINK:
                case T_IPC:
                  return(check_role_fc(target,tid,owner));
                  
                case T_SCD:
                  #ifdef CONFIG_RSBAC_USER_MOD_IOPERM
                  if(tid.scd == ST_ioports)
                    return GRANTED;
                  #endif
                  /* Security Officer? */
                  i_tid.user = owner;
                  if ((err=rsbac_get_attr(FC,
                                     T_USER,
                                     i_tid,
                                     A_fc_role,
                                     &i_attr_val1,
                                     TRUE)))
                    {
                      printk(KERN_WARNING
                             "rsbac_adf_request_fc(): rsbac_get_attr() returned error %i!\n",err);
                      return(NOT_GRANTED);
                    }
                  /* if sec_officer, then grant */
                  if (i_attr_val1.system_role == SR_security_officer)
                    return(GRANTED);
                  /* For booting: if administrator and ioports, then grant */
                  if (   (i_attr_val1.system_role == SR_administrator)
                      && (tid.scd == ST_ioports) )
                    return(GRANTED);
                  else
                    return(NOT_GRANTED);
                  
#ifdef CONFIG_RSBAC_ALLOW_DAC_DISABLE
                /* switching Linux DAC */
                case T_NONE:
                  /* Security Officer? */
                  return fc_check_sysrole(owner, SR_security_officer);
#endif

                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }

        case R_MODIFY_SYSTEM_DATA:
            switch(target)
              {
                case T_SCD:
                  /* target rlimit? no problem, but needed -> grant */
                  if (tid.scd == ST_rlimit)
                    return(GRANTED);
                  /* Administrator? */
                  i_tid.user = owner;
                  if ((err=rsbac_get_attr(FC,
                                     T_USER,
                                     i_tid,
                                     A_fc_role,
                                     &i_attr_val1,
                                     TRUE)))
                    {
                      printk(KERN_WARNING
                             "rsbac_adf_request_fc(): rsbac_get_attr() returned error %i!\n",err);
                      return(NOT_GRANTED);
                    }
                  /* if rsbaclog: grant only for secoff */
                  if(tid.scd == ST_rsbaclog)
                    {
                      if (   (i_attr_val1.system_role == SR_security_officer)
                          || (i_attr_val1.system_role == SR_auditor)
                         )
                        return(GRANTED);
                      else
                        return(NOT_GRANTED);
                    }
                  /* if administrator, then grant all other types */
                  if (i_attr_val1.system_role == SR_administrator)
                    return(GRANTED);
                  else
                    return(NOT_GRANTED);
                  
#ifdef CONFIG_RSBAC_FC_NET_DEV_PROT
                case T_NETDEV:
                  return fc_check_sysrole(owner, SR_administrator);
#endif

                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }

        case R_MOUNT:
        case R_UMOUNT:
            switch(target)
              {
                case T_FILE:
                case T_DIR:
                case T_DEV:
                  /* test owner's fc_role */
                  if(fc_check_sysrole(owner, SR_administrator) == NOT_GRANTED)
                    return NOT_GRANTED;

                  /* test access to dir */
                  return(check_role_fc(target,tid,owner));

                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }

        case R_READ:
            switch(target)
              {
                case T_DIR: 
#ifdef CONFIG_RSBAC_RW
                case T_FILE:
                case T_FIFO:
                case T_IPC:
#endif
                  return(check_role_fc(target,tid,owner));

#if defined(CONFIG_RSBAC_FC_NET_OBJ_PROT)
                case T_NETTEMP:
                  if(fc_check_sysrole(owner, SR_security_officer) == GRANTED)
                    return GRANTED;
                  return fc_check_sysrole(owner, SR_administrator);

                case T_NETOBJ:
                  return(check_role_fc_netobj(request,tid,owner));
#endif

                /* all other cases */
                default: return(DO_NOT_CARE);
              }

        case R_READ_ATTRIBUTE:
            switch(attr)
              {
                case A_system_role:
                case A_fc_role:
                case A_object_category:
                case A_local_object_category:
                case A_remote_object_category:
                #ifdef CONFIG_RSBAC_FC_GEN_PROT
                case A_log_array_low:
                case A_log_array_high:
                case A_log_program_based:
                case A_log_user_based:
                case A_symlink_add_uid:
                case A_symlink_add_rc_role:
                case A_linux_dac_disable:
                #endif
                #ifdef CONFIG_RSBAC_FC_AUTH_PROT
                case A_auth_may_setuid:
                case A_auth_may_set_cap:
                #endif
                  /* Security Officer? */
                  return fc_check_sysrole(owner, SR_security_officer);

                default:
                  return(DO_NOT_CARE);
              }

        case R_READ_OPEN:
            switch(target)
              {
                case T_FILE:
                case T_DIR:
                case T_FIFO:
                case T_DEV:
                case T_IPC:
                  return(check_role_fc(target,tid,owner));

                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }

        case R_REMOVE_FROM_KERNEL:
        case R_SHUTDOWN:
            switch(target)
              {
                case T_NONE:
                  /* test owner's fc_role */
                  return fc_check_sysrole(owner, SR_administrator);

                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }

        case R_SEARCH:
            switch(target)
              {
                case T_DIR: 
                case T_SYMLINK:
                  return(check_role_fc(target,tid,owner));

                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }

        case R_SWITCH_LOG:
            switch(target)
              {
                case T_NONE:
                  /* test owner's fc_role */
                  return fc_check_sysrole(owner, SR_security_officer);

                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }

        case R_SWITCH_MODULE:
            switch(target)
              {
                case T_NONE:
                  /* we need the switch_target */
                  if(attr != A_switch_target)
                    return(UNDEFINED);
                  /* do not care for other modules */
                  if(   (attr_val.switch_target != FC)
                     #ifdef CONFIG_RSBAC_FC_AUTH_PROT
                     && (attr_val.switch_target != AUTH)
                     #endif
                     #ifdef CONFIG_RSBAC_SOFTMODE
                     && (attr_val.switch_target != SOFTMODE)
                     #endif
                    )
                    return(DO_NOT_CARE);
                  /* test owner's fc_role */
                  return fc_check_sysrole(owner, SR_security_officer);

                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }

        case R_TRUNCATE:
            switch(target)
              {
                case T_FILE:
                  return(check_role_fc(target,tid,owner));

                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }

        case R_WRITE:
            switch(target)
              {
                case T_DIR: 
#ifdef CONFIG_RSBAC_RW
                case T_FILE:
                case T_FIFO:
                case T_DEV:
                case T_IPC:
#endif
                  return(check_role_fc(target,tid,owner));

#if defined(CONFIG_RSBAC_FC_NET_OBJ_PROT)
                case T_NETTEMP:
                  return fc_check_sysrole(owner, SR_security_officer);

                case T_NETOBJ:
                  return(check_role_fc_netobj(request,tid,owner));
#endif

                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }

        case R_WRITE_OPEN:
            switch(target)
              {
                case T_FILE:
                case T_FIFO:
                case T_DEV:
                case T_IPC:
                  return(check_role_fc(target,tid,owner));

                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }

#ifdef CONFIG_RSBAC_FC_NET_OBJ_PROT
        case R_BIND:
        case R_LISTEN:
        case R_ACCEPT:
        case R_CONNECT:
        case R_SEND:
        case R_RECEIVE:
            switch(target)
              {
                case T_NETOBJ:
                  return(check_role_fc_netobj(request,tid,owner));

                /* all other cases are unknown */
                default: return(DO_NOT_CARE);
              }
#endif

/*********************/
        default: return DO_NOT_CARE;
      }

    return(result);
  }; /* end of rsbac_adf_request_fc() */


/*****************************************************************************/
/* If the request returned granted and the operation is performed,           */
/* the following function can be called by the AEF to get all aci set        */
/* correctly. For write accesses that are performed fully within the kernel, */
/* this is usually not done to prevent extra calls, including R_CLOSE for    */
/* cleaning up. Because of this, the write boundary is not adjusted - there  */
/* is no user-level writing anyway...                                        */
/* The second instance of target specification is the new target, if one has */
/* been created, otherwise its values are ignored.                           */
/* On success, 0 is returned, and an error from rsbac/error.h otherwise.     */

int  rsbac_adf_set_attr_fc(
                      enum  rsbac_adf_request_t     request,
                            rsbac_pid_t             caller_pid,
                      enum  rsbac_target_t          target,
                      union rsbac_target_id_t       tid,
                      enum  rsbac_target_t          new_target,
                      union rsbac_target_id_t       new_tid,
                      enum  rsbac_attribute_t       attr,
                      union rsbac_attribute_value_t attr_val,
                            rsbac_uid_t             owner)
  {
    int                           err;
    union rsbac_target_id_t       i_tid;
    union rsbac_attribute_value_t i_attr_val1;
    union rsbac_attribute_value_t i_attr_val2;

    switch (request)
      {
        case R_CREATE:
            switch(target)
              {
                case T_IPC: 
                  /* Get fc_role of process owner... */
                  i_tid.user = owner;
                  if ((err=rsbac_get_attr(FC,
                                     T_USER,
                                     i_tid,
                                     A_fc_role,
                                     &i_attr_val1,
                                     TRUE)))
                    {
                      printk(KERN_WARNING
                             "rsbac_adf_set_attr_fc(): rsbac_get_attr() returned error %i!\n",err);
                      return(-RSBAC_EREADFAILED);
                    }
                  /* Derive object_category for this ipc item from owner's */
                  /* fc_role */
                  switch (i_attr_val1.system_role)
                    {
                      case SR_user:
                        return 0;
                      case SR_security_officer:
                        i_attr_val2.object_category = OC_security;
                        break;
                      case SR_administrator:
                        i_attr_val2.object_category = OC_system;
                        break;
                      default:
                        printk(KERN_WARNING
                               "rsbac_adf_set_attr_fc(): invalid fc_role %i!\n",
                               i_attr_val1.system_role);
                        return 0;
                    }
                  /* set object_category for new IPC item */
                  if ((err=rsbac_set_attr(FC,
                                          target,
                                          tid,
                                          A_object_category,
                                          i_attr_val2)))
                    {
                      printk(KERN_WARNING "rsbac_adf_set_attr_fc(): rsbac_set_attr() returned error %i!\n",err);
                      return(-RSBAC_EWRITEFAILED);
                    }
                  return(0);

#if defined(CONFIG_RSBAC_FC_NET_OBJ_PROT)
                case T_NETOBJ:
                  /* Get fc_role of process owner... */
                  i_tid.user = owner;
                  if ((err=rsbac_get_attr(FC,
                                     T_USER,
                                     i_tid,
                                     A_fc_role,
                                     &i_attr_val1,
                                     TRUE)))
                    {
                      printk(KERN_WARNING
                             "rsbac_adf_set_attr_fc(): rsbac_get_attr() returned error %i!\n",err);
                      return(-RSBAC_EREADFAILED);
                    }
                  /* Derive local object_category for this ipc item from owner's */
                  /* fc_role */
                  switch (i_attr_val1.system_role)
                    {
                      case SR_user:
                        return 0;
                      case SR_security_officer:
                        i_attr_val2.object_category = OC_security;
                        break;
                      case SR_administrator:
                        i_attr_val2.object_category = OC_system;
                        break;
                      default:
                        printk(KERN_WARNING
                               "rsbac_adf_set_attr_fc(): invalid fc_role %i!\n",
                               i_attr_val1.system_role);
                        return 0;
                    }
                  /* set local object_category for new IPC item */
                  if ((err=rsbac_set_attr(FC,
                                          target,
                                          tid,
                                          A_local_object_category,
                                          i_attr_val2)))
                    {
                      printk(KERN_WARNING "rsbac_adf_set_attr_fc(): rsbac_set_attr() returned error %i!\n",err);
                      return(-RSBAC_EWRITEFAILED);
                    }
                  return(0);
#endif

                /* all other cases are unknown */
                default:
                  return(0);
              }


/*********************/
        default: return(0);
      }

    return(0);
  }; /* end of rsbac_adf_set_attr_fc() */

/* end of rsbac/adf/fc/main.c */
