/************************************************* */
/* Rule Set Based Access Control                   */
/* Implementation of the Access Control Decision   */
/* Facility (ADF) - Authentification module        */
/* File: rsbac/adf/auth/syscalls.c                 */
/*                                                 */
/* Author and (c) 1999,2000: Amon Ott              */
/*                                                 */
/* Last modified: 19/Sep/2000                      */
/************************************************* */

#include <linux/string.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <rsbac/types.h>
#include <rsbac/aci.h>
#include <rsbac/error.h>
#include <rsbac/auth.h>

#ifndef NULL
#define NULL ((void *) 0)
#endif

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

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

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

int rsbac_auth_add_p_cap(rsbac_pid_t pid,
                         rsbac_uid_t first_uid,
                         rsbac_uid_t last_uid)
  {
/* check only in non-maint mode */
#if defined(CONFIG_RSBAC_AUTH)
    union rsbac_target_id_t       i_tid;
    union rsbac_attribute_value_t i_attr_val1;

    /* check auth_may_set_cap of calling process */
    i_tid.process = current->pid;
    if (rsbac_get_attr(T_PROCESS,
                       i_tid,
                       A_auth_may_set_cap,
                       &i_attr_val1,
                       FALSE))
      {
        printk(KERN_WARNING
               "rsbac_auth_add_p_cap(): rsbac_get_attr() returned error!\n");
        return(-RSBAC_EREADFAILED);
      }
    /* if auth_may_set_cap is not set, then reject */
    if (!i_attr_val1.auth_may_set_cap)
      return(-EPERM);
#endif

    /* OK, check passed. Add the capability. */
    if(rsbac_auth_add_to_p_capset(pid, first_uid, last_uid))
      {
        printk(KERN_WARNING
               "rsbac_auth_add_p_cap(): rsbac_auth_add_to_p_capset() returned error!\n");
        return(-RSBAC_EWRITEFAILED);
      }
    return 0;
  }

int rsbac_auth_remove_p_cap(rsbac_pid_t pid,
                            rsbac_uid_t first_uid,
                            rsbac_uid_t last_uid)
  {
/* check only in non-maint mode */
#if defined(CONFIG_RSBAC_AUTH)
    union rsbac_target_id_t       i_tid;
    union rsbac_attribute_value_t i_attr_val1;

    /* check auth_may_set_cap of calling process */
    i_tid.process = current->pid;
    if (rsbac_get_attr(T_PROCESS,
                       i_tid,
                       A_auth_may_set_cap,
                       &i_attr_val1,
                       FALSE))
      {
        printk(KERN_WARNING
               "rsbac_auth_remove_p_cap(): rsbac_get_attr() returned error!\n");
        return(-RSBAC_EREADFAILED);
      }
    /* if auth_may_set_cap is not set, then reject */
    if (!i_attr_val1.auth_may_set_cap)
      return(-EPERM);
#endif

    /* OK, check passed. Try to remove the capability. */
    return(rsbac_auth_remove_from_p_capset(pid, first_uid, last_uid));
  }

int rsbac_auth_add_f_cap(rsbac_auth_file_t file,
                         rsbac_uid_t first_uid,
                         rsbac_uid_t last_uid)
  {
    /* check has been done in help/syscalls.c: sys_rsbac_auth_add_f_cap */
    if(rsbac_auth_add_to_f_capset(file, first_uid, last_uid))
      {
        printk(KERN_WARNING
               "rsbac_auth_add_f_cap(): rsbac_auth_add_to_f_capset() returned error!\n");
        return(-RSBAC_EWRITEFAILED);
      }
    return 0;
  }

int rsbac_auth_remove_f_cap(rsbac_auth_file_t file,
                            rsbac_uid_t first_uid,
                            rsbac_uid_t last_uid)
  {
    /* check has been done in help/syscalls.c: sys_rsbac_auth_remove_f_cap */
    return(rsbac_auth_remove_from_f_capset(file, first_uid, last_uid));
  }

/* end of rsbac/adf/auth/syscalls.c */
