
/* -*- C++ -*- */

subsystem
#if	KERNEL_SERVER
	  KernelServer
#endif	KERNEL_SERVER
	  security 5200;

#include <mach/std_types.defs>
#include <mach/mach_types.defs>

type labelstr_t = c_string[*:512];

/**
  @brief Retrieve a task label as a label handle
  @param task Target's task port
  @param label Returned label handle

  This call retrieves the label handle of the specified task.

  @return Standard MiG return values (0 for success)
*/

routine mach_get_task_label(task      : ipc_space_t;
			    out label : mach_port_name_t);

/**
  @brief Retrieve a task label in textual form
  @param task Target's task port
  @param policies Comma-delimited list of policies to query
  @param label Returned label text

  This call retrieves an externalized task label for the
  specified task, with respect to the specified policies.

  @return Standard MiG return values (0 for success)
*/

routine mach_get_task_label_text(task      : ipc_space_t;
				 policies  : labelstr_t;
				 out label : labelstr_t);

/**
  @brief Retrieve a port label as a label handle
  @param task Issuer's task port
  @param port Port to query label from
  @param label Returned label handle

  This call retrieves a new label handle for the specified port.
  If the port represents a label handle, KERN_INVALID_ARGUMENT is
  returned.

  @return Standard MiG return values (0 for success)
*/

routine mach_get_label(task      : ipc_space_t;
		       port      : mach_port_name_t;
		       out label : mach_port_name_t);

/**
  @brief Retrieve a port label in textual form
  @param task Issuer's task port
  @param name Port to query label from
  @param policies Comma-delimited list of policies to query
  @param label Returned label text

  This call retrieves an externalized port label for the specified port,
  with respect to the specified policies. If the port represents a label
  handle, the returned label text refers to the stored label and not the
  access control label.

  @return Standard MiG return values (0 for success)
*/

routine mach_get_label_text(task      : ipc_space_t;
			    name      : mach_port_name_t;
			    policies  : labelstr_t;
			    out label : labelstr_t);

/**
  @brief Relabel a port
  @param task Task containing specified ports
  @param name Port to relabel
  @param label String representation of new label

  This call attempts to relabel the specified port to the
  label specified. For label handles, it changes the access control
  label and not the stored label.

  @return Standard MiG return values (0 for success)
*/

routine mach_set_port_label(task      : ipc_space_t;
			    name      : mach_port_name_t;
			    label     : labelstr_t);

/**
  @brief Generic access control check
  @param task Any task port
  @param subj subject label in textual form
  @param obj object label in textual form
  @param serv Service or object class name
  @param perm Permission, or method, within the specified service

  This function provides a general way for a user process to query
  an arbitrary access control decision from the system's security policies.
  Currently, there are no standards for the format of the service and
  permission names. 

  @return Standard MiG return values (0 for success)
*/

routine mac_check_service(task    : ipc_space_t;
			  subject : labelstr_t;
			  object  : labelstr_t;
			  service : labelstr_t;
			  perm    : labelstr_t);

/**
  @brief Generic access control check
  @param task Task containing specified ports (usually caller's)
  @param subj subject label in textual form
  @param obj port containing object label
  @param serv Service or object class name
  @param perm Permission, or method, within the specified service

  This function provides a general way for a user process to query
  an arbitrary access control decision from the system's security policies.
  Currently, there are no standards for the format of the service and
  permission names. If the port is a label handle, the stored label is
  used. Otherwise, its access control label is used.

  @return Standard MiG return values (0 for success)
*/

routine mac_port_check_service_obj(task    : ipc_space_t;
				   subject : labelstr_t;
				   object  : mach_port_name_t;
				   service : labelstr_t;
				   perm    : labelstr_t);

/**
  @brief Generic access control check
  @param task Task containing specified ports (usually caller's)
  @param subj port containing subject label
  @param obj port containing object label
  @param serv Service or object class name
  @param perm Permission, or method, within the specified service

  This function provides a general way for a user process to query
  an arbitrary access control decision from the system's security policies.
  Currently, there are no standards for the format of the service and
  permission names. If any ports are label handles, the stored label is
  used. Otherwise, the access control labels are used.

  @return Standard MiG return values (0 for success)
*/

routine mac_port_check_access(task    : ipc_space_t;
			      subject : mach_port_name_t;
			      object  : mach_port_name_t;
			      service : labelstr_t;
			      perm    : labelstr_t);

/**
  @brief Create a new label handle
  @param task Task to receive new ports (usually caller's)
  @param name Returned label handle port
  @param label String representation of new label

  Creates a new label handle, with the stored label defined by the
  given text. Any task may create a label handle with any valid label,
  not necessarily one that it has permission to access. A port right
  for the new label handle is inserted into the specified task.
  Posession of label handles should not imply any security properties.

  @return Standard MiG return values (0 for success)
*/

routine mac_label_new(task     : ipc_space_t;
		      out name : mach_port_name_t;
		      label    : labelstr_t);

/**
  @brief Request a computed label
  @param task subj,obj,newlabel relative to this task (usually caller's)
  @param subj port containing subject label
  @param obj port containing object label
  @param serv Service or object class name
  @param newlabel Returned label handle port
  
  Ask the loaded policies to compute a label based on the two input labels
  and the service name. There is currently no standard for the service name,
  or even what the input labels represent (Subject and parent object are only
  a suggestion). If any ports are label handles, the stored label is
  used. Otherwise, the access control labels are used. A new label handle
  is created to contain the computed label, and is stored into the
  specified task.

  @return Standard MiG return values (0 for success)
*/

routine mac_request_label(task         : ipc_space_t;
			  subject      : mach_port_name_t;
			  object       : mach_port_name_t;
			  service      : labelstr_t;
			  out newlabel : mach_port_name_t);
