Solaris Trusted Extensions Developer's Guide
Previous Next

Label APIs

This section describes the APIs that are available for basic label operations. To use these APIs, you must include the following header file:

#include <tsol/label.h>

The label APIs compile with the -ltsol library option.

The Trusted Extensions APIs include data types for the following:

  • Sensitivity label – The m_label_t type definition represents a sensitivity label. The m_label_t structure is opaque.

    Interfaces accept a variable of type m_label_t as a parameter. Interfaces can return sensitivity labels in a variable of type m_label_t. The m_label_t type definition is compatible with the blevel_t structure.

  • Sensitivity label range – The brange_t data structure represents a range of sensitivity labels. The structure holds a minimum label and a maximum label. The structure fields are referred to as variable.lower_bound and variable.upper_bound.

The APIs for the following operations are described in this section:

  • Detecting a Trusted Extensions system

  • Accessing the process sensitivity label

  • Allocating and freeing memory for labels

  • Obtaining and setting the label of a file

  • Obtaining label ranges

  • Accessing labels in zones

  • Obtaining the remote host type

  • Translating between labels and strings

  • Comparing labels

Detecting a Trusted Extensions System

The is_system_labeled() routine is used to determine whether you are running on a Trusted Extensions system. The following routine description includes the prototype declaration for each routine:

int is_system_labeled(void);

The is_system_labeled() routine returns TRUE (1) if the Trusted Extensions software is installed and active. Otherwise, it returns FALSE (0).

See the is_system_labeled(3C) man page. For an example of this routine's use, see get_peer_label() Label-Aware Function.

You can also use these other interfaces to determine whether the system is labeled:

  • X client. If you are writing an X client that depends on multilevel functionality, use the XQueryExtension() routine to query the X server for the SUN_TSOL extension.

  • Shell script. If you are writing a shell script that will determine whether the system is labeled, use the plabel command. See the plabel(1) man page.

    The following example shows the smf_is_system_labeled() function used by the /onnv/onnv-gate/usr/src/cmd/svc/shell/smf_include.sh script:

    #
    #  Returns zero (success) if system is labeled (aka Trusted Extensions).
    #  1 otherwise.
    #
    smf_is_system_labeled() {
            [ ! -x /bin/plabel ] && return 1
            /bin/plabel > /dev/null 2>&1
            return $?
    }

Accessing the Process Sensitivity Label

The getplabel() and ucred_getlabel() routines are used to access the sensitivity label of a process. The following routine descriptions include the prototype declaration for each routine:

int getplabel(m_label_t *label_p);

The getplabel() routine obtains the process label of the calling process.

See the getplabel(3TSOL) man page.

m_label_t *ucred_getlabel(const ucred_t *uc);

The ucred_getlabel() routine obtains the label in the credential of the remote process.

See the ucred_getlabel(3C) man page. For an example of this routine's use, see get_peer_label() Label-Aware Function.

Allocating and Freeing Memory for Labels

The m_label_alloc(), m_label_dup(), and m_label_free() routines are used to allocate and free memory for labels. The following routine descriptions include the prototype declaration for each routine:

m_label_t *m_label_alloc(const m_label_type_t label_type);

The m_label_alloc() routine allocates a label in an m_label_t data structure on the heap. Labels must be allocated before calling routines such as getlabel() and fgetlabel(). Some routines, such as str_to_label(), automatically allocate an m_label_t structure.

When you create a label by using the m_label_alloc() routine, you can set the label type to be a sensitivity label or a clearance label.

int m_label_dup(m_label_t **dst, const m_label_t *src);

The m_label_dup() routine duplicates a label.

void m_label_free(m_label_t *label);

The m_label_free() routine frees the memory that was allocated for a label.

When you allocate an m_label_t structure or when you call another routine that automatically allocates an m_label_t structure, you are responsible for freeing the allocated memory. The m_label_free() routine frees the allocated memory.

See the m_label(3TSOL) man page.

Obtaining and Setting the Label of a File

The setflabel() routine, the getlabel() system call, and the fgetlabel() system call are used to obtain and set the label of a file. The following descriptions include the prototype declarations for the routine and the system calls:

int setflabel(const char *path, const m_label_t *label_p);

The setflabel() routine changes the sensitivity label of a file. When the sensitivity label of a file changes, the file is moved to a zone that corresponds to the new label. The file is moved to a new path name that is relative to the root of the other zone.

See the setflabel(3TSOL) man page.

For example, if you use the setflabel() routine to change the label of the file /zone/internal/documents/designdoc.odt from INTERNAL to RESTRICTED, the new path of the file will be /zone/restricted/documents/designdoc.odt. Note that if the destination directory does not exist, the file is not moved.

When you change the sensitivity label of a file, the original file is deleted. The only exception occurs when the source and destination file systems are loopback-mounted from the same underlying file system. In this case, the file is renamed.

When a process creates an object, the object inherits the sensitivity label of its calling process. The setflabel() routine programmatically sets the sensitivity label of a file system object.

The File Manager application and the setlabel command permit an authorized user to move an existing file to a different sensitivity label. See the setlabel(1) man page.

int getlabel(const char *path, m_label_t *label_p);

The getlabel() system call obtains the label of a file that is specified by path. The label is stored in an m_label_t structure that you allocate.

See the getlabel(2) man page.

int fgetlabel(int fd, m_label_t *label_p);

The fgetlabel() system call obtains the label of an open file by specifying a file descriptor.

When you allocate an m_label_t structure, you are responsible for freeing the allocated memory by using the m_label_free() routine. See the m_label(3TSOL) man page.

Obtaining Label Ranges

The getuserrange() and getdevicerange() routines are used to obtain the label range of a user and a device, respectively. The following routine descriptions include the prototype declaration for each routine:

m_range_t *getuserrange(const char *username);

The getuserrange() routine obtains the label range of the specified user. The lower bound in the range is used as the initial workspace label when a user logs in to a multilevel desktop. The upper bound, or clearance, is used as an upper limit to the available labels that a user can assign to labeled workspaces.

The default value for a user's label range is specified in the label_encodings file. The value can be overridden by the user_attr file.

See the setflabel(3TSOL), label_encodings(4), and user_attr(4) man pages.

bl_range_t *getdevicerange(const char *device);

The getdevicerange() routine obtains the label range of a user-allocatable device. If no label range is specified for the device, the default range has an upper bound of ADMIN_HIGH and a lower bound of ADMIN_LOW.

You can use the list_devices command to show the label range for a device.

See the list_devices(1) and getdevicerange(3TSOL) man pages.

Accessing Labels in Zones

These functions obtain label information from objects in zones. The following routine descriptions include the prototype declaration for each routine:

char *getpathbylabel(const char *path, char *resolved_path, size_t bufsize, const m_label_t *sl);

The getpathbylabel() routine expands all symbolic links and resolves references to /./, /../, removes extra slash (/) characters, and stores the zone path name in the buffer named by resolved_path. The bufsize variable specifies the size in bytes of this buffer. The resulting path does not have any symbolic link components or any /./, /../. This function can only be called from the global zone.

The zone path name is relative to the sensitivity label, sl. To specify a sensitivity label for a zone name that does not exist, the process must assert either the priv_file_upgrade_sl or the priv_file_downgrade_sl privilege, depending on whether the specified sensitivity label dominates or does not dominate the process sensitivity label.

See the getpathbylabel(3TSOL) man page.

m_label_t *getzoneidbylabel(const m_label_t *label);

The getzoneidbylabel() routine returns the zone ID of the zone whose label is label. This routine requires that the specified zone's state is at least ZONE_IS_READY. The zone of the calling process must dominate the specified zone's label, or the calling process must be in the global zone.

See the getzoneidbylabel(3TSOL) man page.

m_label_t *getzonelabelbyid(zoneid_t zoneid);

The getzonelabelbyid() routine returns the MAC label of zoneid. This routine requires that the specified zone's state is at least ZONE_IS_READY. The zone of the calling process must dominate the specified zone's label, or the calling process must be in the global zone.

See the getzonelabelbyid(3TSOL) man page.

m_label_t *getzonelabelbyname(const char *zonename);

The getzonelabelbyname() routine returns the MAC label of the zone whose name is zonename. This routine requires that the specified zone's state is at least ZONE_IS_READY. The zone of the calling process must dominate the specified zone's label, or the calling process must be in the global zone.

See the getzonelabelbyname(3TSOL) man page.

m_label_t *getzonerootbyid(zoneid_t zoneid);

The getzonerootbyid() routine returns the root path name of zoneid. This routine requires that the specified zone's state is at least ZONE_IS_READY. The zone of the calling process must dominate the specified zone's label, or the calling process must be in the global zone. The returned path name is relative to the root path of the caller's zone.

See the getzonerootbyid(3TSOL) man page.

m_label_t *getzonerootbylabel(const m_label_t *label);

The getzonerootbylabel() routine returns the root path name of the zone whose label is label. This routine requires that the specified zone's state is at least ZONE_IS_READY. The zone of the calling process must dominate the specified zone's label, or the calling process must be in the global zone. The returned path name is relative to the root path of the caller's zone.

See the getzonerootbylabel(3TSOL) man page.

m_label_t *getzonerootbyname(const char *zonename);

The getzonerootbyname() routine returns the root path name of zonename. This routine requires that the specified zone's state is at least ZONE_IS_READY. The zone of the calling process must dominate the specified zone's label, or the calling process must be in the global zone. The returned path name is relative to the root path of the caller's zone.

See the getzonerootbyname(3TSOL) man page.

Obtaining the Remote Host Type

This routine determines the remote host type. The following routine description includes the prototype declaration:

tsol_host_type_t tsol_getrhtype(char *hostname);

The tsol_getrhtype() routine queries the kernel-level network information to determine the host type that is associated with the specified host name. hostname can be a regular host name, an IP address, or a network wildcard address. The returned value is one of the enumerated types that is defined in the tsol_host_type_t structure. Currently, these types are UNLABELED and SUN_CIPSO.

See the tsol_getrhtype(3TSOL) man page.

Translating Between Labels and Strings

The label_to_str() and str_to_label() routines are used to translate between labels and strings. The following routine descriptions include the prototype declaration for each routine:

int label_to_str(const m_label_t *label, char **string, const m_label_str_t conversion_type, uint_t flags);

The label_to_str() routine translates a label, m_label_t, to a string. You can use this routine to translate a label into a string that hides the classification name. This format is suitable for storing in public objects. The calling process must dominate the label to be translated, or the process must have the sys_trans_label privilege.

See the label_to_str(3TSOL) man page.

The label_to_str() routine allocates memory for the translated string. The caller must free this memory by calling the free() routine.

See the free(3C) man page.

int str_to_label(const char *string, m_label_t **label, const m_label_type_t label_type, uint_t flags, int *error);

The str_to_label() routine translates a label string to a label, m_label_t. When you allocate an m_label_t structure, you must free the allocated memory by using the m_label_free() routine.

When you create a label by using the str_to_label() routine, you can set the label type to be a sensitivity label or a clearance label.

See the str_to_label(3TSOL) and m_label(3TSOL) man pages.

Readable Versions of Labels

The label_to_str() routine provides readable versions of labels. The M_LABEL conversion type returns a string that is classified at that label. The M_INTERNAL conversion type returns a string that is unclassified. The classified string version is typically used for displays, as in windows. The classified string might not be suitable for storage. Several conversion types are offered for printing purposes. All printing types show a readable string that is classified at the label that the string shows.

The conversion_type parameter controls the type of label conversion. The following are valid values for conversion_type, although not all types of conversion are valid for both level types:

  • M_LABEL is a string of the label that is based on the type of label: sensitivity or clearance. This label string is classified at the level of the label and is therefore not safe for storing in a public object. For example, an M_LABEL string such as CONFIDENTIAL is not safe for storing in a public directory because the words in the label are often classified.

  • M_INTERNAL is a string of an unclassified representation of the label. This string is safe for storing in a public object. For example, an M_INTERNAL string such as 0x0002-04-48 is safe for storing in an LDAP database.

  • M_COLOR is a string that represents the color that the security administrator has associated with the label. The association between the label and the color is stored in the LOCAL DEFINITIONS section of the label_encodings file.

  • PRINTER_TOP_BOTTOM is a string used as the top and the bottom label of banner and trailer pages.

  • PRINTER_LABEL is a string used as the downgrade warning on the banner page.

  • PRINTER_CAVEATS is a string used in the caveats section on the banner page.

  • PRINTER_CHANNEL is a string used as the handling channels on the banner page.

Label Encodings File

The label_to_str() routine uses the label definitions in the label_encodings file. The encodings file is a text file that is maintained by the security administrator. The file contains site-specific label definitions and constraints. This file is kept in /etc/security/tsol/label_encodings. For information about the label_encodings file, see Solaris Trusted Extensions Label Administration, Compartmented Mode Workstation Labeling: Encodings Format, and the label_encodings(4) man page.

Comparing Labels

The blequal(), bldominates(), and blstrictdom() routines are used to compare labels. The blinrange() routine is used to determine whether a label is within a specified label range. In these routines, a level refers to a classification and a set of compartments in a sensitivity label or in a clearance label.

int blequal(const blevel_t *level1, const blevel_t *level2);

The blequal() routine compares two labels to determine whether level1 equals level2.

int bldominates(const m_label_t *level1, const m_label_t *level2);

The bldominates() routine compares two labels to determine whether level1 dominates level2.

int blstrictdom(const m_label_t *level1, const m_label_t *level2);

The blstrictdom() routine compares two labels to determine whether level1 strictly dominates level2.

int blinrange(const m_label_t *level, const brange_t *range);

The blinrange() routine determines whether the label, level, is within the specified range, range.

These routines return a nonzero value when the comparison is true and a value of 0 when the comparison is false. For more information about these routines, see the blcompare(3TSOL) man page. For examples of how these routines are used in the multilevel printing application, see Validating the Label Request Against the Printer's Label Range.

For more information about label relationships, see Label Relationships.

The blmaximum() and blminimum() routines are used to determine the upper and lower bounds of the specified label range.

void blmaximum(m_label_t *maximum_label, const m_label_t *bounding_label);

The blmaximum() routine compares two labels to find the least upper bound of the range. The least upper bound is the lower of two clearances, which is used to determine whether you have access to a system of a particular clearance.

For instance, use this routine to determine the label to use when creating a new labeled object that combines information from two other labeled objects. The label of the new object will dominate both of the original labeled objects.

See the blminmax(3TSOL) man page.

void blminimum(m_label_t *minimum_label, const m_label_t *bounding_label);

The blminimum() routine compares two labels to find the label that represents the greatest lower bound of the range that is bounded by the two levels. The greatest lower bound is the higher of two labels, which is also used to determine whether you have access to a system of a particular clearance.

See the blminmax(3TSOL) man page.

Previous Next