<?Pub UDT _bookmark _target?><?Pub EntList bsol dash hellip gt lt minus?><?Pub CX solbook(book(title()bookinfo()chapter()?><chapter id="labelapi-1"><title>Labels and Clearances</title><highlights><para>This chapter describes the Solaris Trusted Extensions APIs for performing basic label operations such as initializing labels, and comparing labels and clearances. This chapter also describes the APIs for accessing the label of a process.</para><para>For examples of how the Trusted Extensions APIs are used in the Solaris OS, see the Solaris source code. Go to the <ulink url="http://opensolaris.org/" type="text_url">Open Solaris web site</ulink> and click Source Browser in the left navigation bar. Use the Source Browser to search through the Solaris source code.</para><itemizedlist><para>This chapter covers the following topics:</para><listitem><para><olink targetptr="labelapi-32" remap="internal">Privileged Operations and Labels</olink></para>
</listitem><listitem><para><olink targetptr="labelapi-22" remap="internal">Label APIs</olink></para>
</listitem><listitem><para><olink targetptr="labelapi-31" remap="internal">Acquiring a Sensitivity Label</olink></para>
</listitem>
</itemizedlist><para><olink targetptr="labelcode-1" remap="internal">Chapter&nbsp;3, Label Code Examples</olink> provides code examples for the programming interfaces that are described in this chapter.</para>
</highlights><sect1 id="labelapi-32"><title>Privileged Operations and Labels</title><indexterm><primary>labels</primary><secondary>privileged tasks</secondary>
</indexterm><indexterm><primary>security attributes</primary><secondary>accessing labels</secondary>
</indexterm><indexterm><primary>security policy</primary><secondary>labels</secondary>
</indexterm><indexterm><primary>access</primary><secondary>file labels</secondary>
</indexterm><indexterm><primary>privileged tasks</primary><secondary>labels</secondary>
</indexterm><indexterm><primary>security policy</primary><secondary>label guidelines</secondary>
</indexterm><para>When an operation can bypass or override the security policy, the operation requires special privileges in its effective set.</para><itemizedlist><para>Privileges are added to the effective set programmatically or administratively in these ways:</para><listitem><para>If the executable file is owned by <literal>root</literal> and has the set user ID permission bit set, it starts with all privileges in its effective set. For example, the CDE File Manager starts with all privileges in its effective set. Then, File Manager programmatically relinquishes most of its privileges to retain only the ones it needs to perform drag-and-drop operations across labels.</para>
</listitem><listitem><para>The administrator can specify privileges in manifest files for SMF services or in the RBAC database <filename>exec_attr</filename> file for general commands. For more information about this file, see the <olink targetdoc="refman" targetptr="exec-attr-4" remap="external"><citerefentry><refentrytitle>exec_attr</refentrytitle><manvolnum>4</manvolnum></citerefentry></olink> man page.</para>
</listitem>
</itemizedlist><para>The operation needs special privileges when translating binary labels and when upgrading or downgrading sensitivity labels.</para><para>Users and roles can run operations with special privileges. These privileges can be specified by using <firstterm>rights profiles</firstterm>. Applications can be written to run certain functions with certain privileges, as well. When you write an application that must assume special privileges, make sure that you enable the privilege only while running the function that needs it and that you remove the privilege when the function completes. This practice is referred to as <firstterm>privilege bracketing</firstterm>. For more information, see <olink targetdoc="gssapipg" remap="external"><citetitle remap="book">Solaris Security for Developers Guide</citetitle></olink>.</para><itemizedlist><listitem><para><indexterm><primary><constant>sys_trans_label</constant> privilege</primary></indexterm><indexterm><primary>privileges</primary><secondary><constant>sys_trans_label</constant></secondary></indexterm><indexterm><primary>security policy</primary><secondary>translating labels</secondary></indexterm><indexterm><primary>translation</primary><secondary>privileges needed</secondary></indexterm><emphasis role="strong">Translating binary labels &ndash;</emphasis> You can translate a label between its internal representation and a string. If the label being translated is not dominated by the label of the process, the calling process requires the <constant>sys_trans_label</constant> privilege to perform the translation.</para>
</listitem><listitem><para><indexterm><primary><constant>file_owner</constant> privilege</primary></indexterm><indexterm><primary>privileges</primary><secondary><constant>file_owner</constant></secondary></indexterm><indexterm><primary>files</primary><secondary>label privileges</secondary></indexterm><emphasis role="strong">Upgrading or downgrading sensitivity labels &ndash;</emphasis> You can <firstterm>downgrade</firstterm> or <firstterm>upgrade</firstterm> the sensitivity label on a file. If the file is not owned by the calling process, the calling process requires the <constant>file_owner</constant> privilege in its effective set. For more information, see the <olink targetdoc="refman" targetptr="setflabel-3tsol" remap="external"><citerefentry><refentrytitle>setflabel</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man page.</para><para><indexterm><primary>privileges</primary><secondary><constant>file_downgrade_sl</constant></secondary></indexterm><indexterm><primary><constant>file_downgrade_sl</constant> privilege</primary></indexterm><indexterm><primary>downgrading labels</primary><secondary>privileges needed</secondary></indexterm><indexterm><primary>labels</primary><secondary>privileges</secondary><tertiary>downgrading labels</tertiary></indexterm>A process can set the sensitivity label on a file system object to a new sensitivity label that does not dominate the object's existing sensitivity label with the <constant>file_downgrade_sl</constant> privilege in its effective set. The <constant>file_downgrade_sl</constant> privilege also allows a file to be relabeled to a disjoint label.</para><para><indexterm><primary>privileges</primary><secondary><constant>file_upgrade_sl</constant></secondary></indexterm><indexterm><primary>upgrading labels</primary><secondary>privileges needed</secondary></indexterm><indexterm><primary>labels</primary><secondary>privileges</secondary><tertiary>upgrading labels</tertiary></indexterm>A process can set the sensitivity label on a file system object to a new sensitivity label that dominates the object's existing sensitivity label with the <constant>file_upgrade_sl</constant> privilege in its effective set.</para>
</listitem>
</itemizedlist><itemizedlist><para>Most applications do not use privileges to bypass access controls because the applications operate in one of the following ways:</para><listitem><para>The application is launched at one sensitivity label and accesses data in objects at that same sensitivity label.</para>
</listitem><listitem><para>The application is launched at one sensitivity label and accesses data in objects at other sensitivity labels, but the mandatory access operations are permitted by the system security policy. For example, read-down is allowed by MAC.</para>
</listitem>
</itemizedlist><para><indexterm><primary>privileges</primary><secondary><constant>file_dac_search</constant></secondary></indexterm><indexterm><primary>privileges</primary><secondary><constant>file_dac_read</constant></secondary></indexterm><indexterm><primary>privileges</primary><secondary><constant>file_dac_write</constant></secondary></indexterm><indexterm><primary>access</primary><secondary>guidelines for labels</secondary></indexterm>If an application tries to access data at sensitivity labels other than the sensitivity label of its process and access is denied, the process needs privileges to gain access. <firstterm>Privileges</firstterm> enable an application to bypass MAC or DAC. For example, the <constant>file_dac_read</constant>, <constant>file_dac_write</constant>, and <constant>file_dac_search</constant> privileges bypass DAC. The <constant>file_upgrade_sl</constant> and <constant>file_downgrade_sl</constant> privileges bypass MAC. No matter how access is obtained, the application design must not compromise the classification of the data that is accessed.</para><para><indexterm><primary>downgrading labels</primary><secondary>guidelines</secondary></indexterm><indexterm><primary>upgrading labels</primary><secondary>guidelines</secondary></indexterm><indexterm><primary>labels</primary><secondary>upgrading guidelines</secondary></indexterm><indexterm><primary>labels</primary><secondary>downgrading guidelines</secondary></indexterm>When your application changes its own sensitivity label or the sensitivity label of another object, be sure to close all file descriptors. An open file descriptor might leak sensitive data to other processes.</para>
</sect1><sect1 id="labelapi-22"><title>Label APIs</title><indexterm><primary>APIs</primary><secondary>labels</secondary>
</indexterm><indexterm><primary>label APIs</primary>
</indexterm><indexterm><primary>compile</primary><secondary>label libraries</secondary>
</indexterm><indexterm><primary>libraries, compile</primary><secondary>label APIs</secondary>
</indexterm><indexterm><primary>header files</primary><secondary>label APIs</secondary>
</indexterm><para>This section describes the APIs that are available for basic label operations. To use these APIs, you must include the following header file:</para><programlisting>#include <filename class="headerfile">tsol/label.h</filename></programlisting><para>The label APIs compile with the <option>ltsol</option> library option.</para><itemizedlist><para><indexterm><primary>data types</primary><secondary>label APIs</secondary></indexterm>The Trusted Extensions APIs include data types for the following:</para><listitem><para><indexterm><primary><structname>m_label_t</structname> type</primary></indexterm><indexterm><primary>label data types</primary><secondary>sensitivity labels</secondary></indexterm><emphasis role="strong">Sensitivity label &ndash;</emphasis> The <structname>m_label_t</structname> type definition represents a sensitivity label. The <structname>m_label_t</structname> structure is opaque.</para><para>Interfaces accept a variable of type <structname>m_label_t</structname> as a parameter. Interfaces can return sensitivity labels in a variable of type <structname>m_label_t</structname>. The <structname>m_label_t</structname> type definition is compatible with the <structname>blevel_t</structname> structure.</para>
</listitem><listitem><para><indexterm><primary>label ranges</primary><secondary>file systems</secondary><tertiary>data structure</tertiary></indexterm><indexterm><primary>labels</primary><secondary>ranges</secondary></indexterm><indexterm><primary><structname>brange_t</structname> type</primary></indexterm><indexterm><primary>label data types</primary><secondary>label ranges</secondary></indexterm><emphasis role="strong">Sensitivity label range &ndash;</emphasis> The <structname>brange_t</structname> 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 <literal>variable.lower_bound</literal> and <literal>variable.upper_bound</literal>.</para>
</listitem>
</itemizedlist><itemizedlist><para>The APIs for the following operations are described in this section:</para><listitem><para>Detecting a Trusted Extensions system</para>
</listitem><listitem><para>Accessing the process sensitivity label</para>
</listitem><listitem><para>Allocating and freeing memory for labels</para>
</listitem><listitem><para>Obtaining and setting the label of a file</para>
</listitem><listitem><para>Obtaining label ranges</para>
</listitem><listitem><para>Accessing labels in zones</para>
</listitem><listitem><para>Obtaining the remote host type</para>
</listitem><listitem><para>Translating between labels and strings</para>
</listitem><listitem><para>Comparing labels</para>
</listitem>
</itemizedlist><sect2 id="detectingtxsystem"><title>Detecting a Trusted Extensions System</title><indexterm><primary><function>is_system_labeled</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>is_system_labeled</function></secondary>
</indexterm><para>The <function>is_system_labeled</function> 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:</para><variablelist termlength="wholeline"><varlistentry><term><literal>int is_system_labeled(void);</literal></term><listitem><para>The <function>is_system_labeled</function> routine returns <symbol>TRUE</symbol> (<constant>1</constant>) if the Trusted Extensions software is installed and active. Otherwise, it returns <symbol>FALSE</symbol> (<constant>0</constant>).</para><para>See the <olink targetdoc="refman" targetptr="is-system-labeled-3c" remap="external"><citerefentry><refentrytitle>is_system_labeled</refentrytitle><manvolnum>3C</manvolnum></citerefentry></olink> man page. For an example of this routine's use, see <olink targetptr="labelprint-5" remap="internal">get_peer_label() Label-Aware Function</olink>.</para>
</listitem>
</varlistentry>
</variablelist><itemizedlist><para>You can also use these other interfaces to determine whether the system is labeled:</para><listitem><para><indexterm><primary>library routines</primary><secondary><function>XQueryExtension</function></secondary></indexterm><emphasis role="strong">X client.</emphasis> If you are writing an X client that depends on multilevel functionality, use the <function>XQueryExtension</function> routine to query the X server for the <constant>SUN_TSOL</constant> extension.</para>
</listitem><listitem><para><indexterm><primary><command>plabel</command> command</primary></indexterm><emphasis role="strong">Shell script.</emphasis> If you are writing a shell script that will determine whether the system is labeled, use the <command>plabel</command> command. See the <olink targetdoc="refman" targetptr="plabel-1" remap="external"><citerefentry><refentrytitle>plabel</refentrytitle><manvolnum>1</manvolnum></citerefentry></olink> man page.</para><para><indexterm><primary>determining whether a system is labeled</primary><secondary>example</secondary></indexterm>The following example shows the <function>smf_is_system_labeled</function> function used by the <filename>/onnv/onnv-gate/usr/src/cmd/svc/shell/smf_include.sh</filename> script:</para><programlisting>#
#  Returns zero (success) if system is labeled (aka Trusted Extensions).
#  1 otherwise.
#
smf_is_system_labeled() {
		[ ! -x /bin/plabel ] &amp;&amp; return 1
		/bin/plabel &gt; /dev/null 2&gt;&amp;1
		return $?
}</programlisting>
</listitem>
</itemizedlist>
</sect2><sect2 id="labelapi-30"><title>Accessing the Process Sensitivity Label</title><indexterm><primary><function>getplabel</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>getplabel</function></secondary>
</indexterm><indexterm><primary><function>ucred_getlabel</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>ucred_getlabel</function></secondary>
</indexterm><para>The <function>getplabel</function> and <function>ucred_getlabel</function> routines are used to access the sensitivity label of a process. The following routine descriptions include the prototype declaration for each routine:</para><variablelist termlength="wholeline"><varlistentry><term><literal>int getplabel(m_label_t *label_p);</literal></term><listitem><para>The <function>getplabel</function> routine obtains the process label of the calling process.</para><para>See the <olink targetdoc="refman" targetptr="getplabel-3tsol" remap="external"><citerefentry><refentrytitle>getplabel</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man page.</para>
</listitem>
</varlistentry><varlistentry><term><literal>m_label_t *ucred_getlabel(const ucred_t *uc);</literal></term><listitem><para>The <function>ucred_getlabel</function> routine obtains the label in the credential of the remote process.</para><para>See the <olink targetdoc="refman" targetptr="ucred-getlabel-3c" remap="external"><citerefentry><refentrytitle>ucred_getlabel</refentrytitle><manvolnum>3C</manvolnum></citerefentry></olink> man page. For an example of this routine's use, see <olink targetptr="labelprint-5" remap="internal">get_peer_label() Label-Aware Function</olink>.</para>
</listitem>
</varlistentry>
</variablelist>
</sect2><sect2 id="labelapi-36"><title>Allocating and Freeing Memory for Labels</title><indexterm><primary><function>m_label_alloc</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary><function>m_label_dup</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary><function>m_label_free</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>m_label_alloc</function></secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>m_label_dup</function></secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>m_label_free</function></secondary>
</indexterm><para>The <function>m_label_alloc</function>, <function>m_label_dup</function>, and <function>m_label_free</function> routines are used to allocate and free memory for labels. The following routine descriptions include the prototype declaration for each routine:</para><variablelist termlength="wholeline"><varlistentry><term><literal>m_label_t *m_label_alloc(const m_label_type_t label_type);</literal></term><listitem><para>The <function>m_label_alloc</function> routine allocates a label in an <structname>m_label_t</structname> data structure on the heap. Labels must be allocated before calling routines such as <function>getlabel</function> and <function>fgetlabel</function>. Some routines, such as <function>str_to_label</function>, automatically allocate an <structname>m_label_t</structname> structure.</para><para>When you create a label by using the <function>m_label_alloc</function> routine, you can set the label type to be a sensitivity label or a clearance label.</para>
</listitem>
</varlistentry><varlistentry><term><literal>int m_label_dup(m_label_t **dst, const m_label_t *src);</literal></term><listitem><para>The <function>m_label_dup</function> routine duplicates a label.</para>
</listitem>
</varlistentry><varlistentry><term><literal>void m_label_free(m_label_t *label);</literal></term><listitem><para>The <function>m_label_free</function> routine frees the memory that was allocated for a label.</para><para>When you allocate an <structname>m_label_t</structname> structure or when you call another routine that automatically allocates an <structname>m_label_t</structname> structure, you are responsible for freeing the allocated memory. The <function>m_label_free</function> routine frees the allocated memory.</para><para>See the <olink targetdoc="refman" targetptr="m-label-3tsol" remap="external"><citerefentry><refentrytitle>m_label</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man page.</para>
</listitem>
</varlistentry>
</variablelist>
</sect2><sect2 id="labelapi-29"><title>Obtaining and Setting the Label of a File</title><indexterm><primary><function>fgetlabel</function> system call</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary><function>getlabel</function> system call</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary><function>setflabel</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary>system calls</primary><secondary><function>fgetlabel</function> routine</secondary>
</indexterm><indexterm><primary>system calls</primary><secondary><function>getlabel</function> routine</secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>setflabel</function></secondary>
</indexterm><para>The <function>setflabel</function> routine, the <function>getlabel</function> system call, and the <function>fgetlabel</function> 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:</para><variablelist termlength="wholeline"><varlistentry><term><literal>int setflabel(const char *path, const m_label_t *label_p);</literal></term><listitem><para><indexterm><primary>labels</primary><secondary>objects</secondary></indexterm>The <function>setflabel</function> 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.</para><para>See the <olink targetdoc="refman" targetptr="setflabel-3tsol" remap="external"><citerefentry><refentrytitle>setflabel</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man page.</para><para>For example, if you use the <function>setflabel</function> routine to change the label of the file <filename>/zone/internal/documents/designdoc.odt</filename> from <constant>INTERNAL</constant> to <constant>RESTRICTED</constant>, the new path of the file will be <filename>/zone/restricted/documents/designdoc.odt</filename>. Note that if the destination directory does not exist, the file is not moved.</para><para>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.</para><para>When a process creates an object, the object inherits the sensitivity label of its calling process. The <function>setflabel</function> routine programmatically sets the sensitivity label of a file system object.</para><para>The File Manager application and the <command>setlabel</command> command permit an authorized user to move an existing file to a different sensitivity label. See the <olink targetdoc="refman" targetptr="setlabel-1" remap="external"><citerefentry><refentrytitle>setlabel</refentrytitle><manvolnum>1</manvolnum></citerefentry></olink> man page.</para>
</listitem>
</varlistentry><varlistentry><term><literal>int getlabel(const char *path, m_label_t *label_p);</literal></term><listitem><para>The <function>getlabel</function> system call obtains the label of a file that is specified by <replaceable>path</replaceable>. The label is stored in an <structname>m_label_t</structname> structure that you allocate.</para><para>See the <olink targetdoc="refman" targetptr="getlabel-2" remap="external"><citerefentry><refentrytitle>getlabel</refentrytitle><manvolnum>2</manvolnum></citerefentry></olink> man page.</para>
</listitem>
</varlistentry><varlistentry><term><literal>int fgetlabel(int fd,  m_label_t *label_p);</literal></term><listitem><para>The <function>fgetlabel</function> system call obtains the label of an open file by specifying a file descriptor.</para>
</listitem>
</varlistentry>
</variablelist><para>When you allocate an <structname>m_label_t</structname> structure, you are responsible for freeing the allocated memory by using the <function>m_label_free</function> routine. See the <olink targetdoc="refman" targetptr="m-label-3tsol" remap="external"><citerefentry><refentrytitle>m_label</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man page.</para>
</sect2><sect2 id="obtaininglabelranges"><title>Obtaining Label Ranges</title><indexterm><primary><function>getuserrange</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary><function>getdevicerange</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>getuserrange</function></secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>getdevicerange</function></secondary>
</indexterm><para>The <function>getuserrange</function> and <function>getdevicerange</function> 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:</para><variablelist termlength="wholeline"><varlistentry><term><literal>m_range_t *getuserrange(const char *username);</literal></term><listitem><para>The <function>getuserrange</function> 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.</para><para>The default value for a user's label range is specified in the <filename>label_encodings</filename> file. The value can be overridden by the <filename>user_attr</filename> file.</para><para>See the <olink targetdoc="refman" targetptr="setflabel-3tsol" remap="external"><citerefentry><refentrytitle>setflabel</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink>, <olink targetdoc="refman" targetptr="label-encodings-4" remap="external"><citerefentry><refentrytitle>label_encodings</refentrytitle><manvolnum>4</manvolnum></citerefentry></olink>, and <olink targetdoc="refman" targetptr="user-attr-4" remap="external"><citerefentry><refentrytitle>user_attr</refentrytitle><manvolnum>4</manvolnum></citerefentry></olink> man pages.</para>
</listitem>
</varlistentry><varlistentry><term><literal>bl_range_t *getdevicerange(const char *device);</literal></term><listitem><para>The <function>getdevicerange</function> 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 <constant>ADMIN_HIGH</constant> and a lower bound of <constant>ADMIN_LOW</constant>.</para><para>You can use the <command>list_devices</command> command to show the label range for a device.</para><para>See the <olink targetdoc="refman" targetptr="list-devices-1" remap="external"><citerefentry><refentrytitle>list_devices</refentrytitle><manvolnum>1</manvolnum></citerefentry></olink> and <olink targetdoc="refman" targetptr="getdevicerange-3tsol" remap="external"><citerefentry><refentrytitle>getdevicerange</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man pages.</para>
</listitem>
</varlistentry>
</variablelist>
</sect2><sect2 id="accessinglabelsinzones"><title>Accessing Labels in Zones</title><indexterm><primary><function>getpathbylabel</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary><function>getzonelabelbyid</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary><function>getzonelabelbyname</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary><function>getzoneidbylabel</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary><function>getzonerootbyid</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary><function>getzonerootbylabel</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary><function>getzonerootbyname</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>getpathbylabel</function></secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>getzonelabelbyid</function></secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>getzonelabelbyname</function></secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>getzoneidbylabel</function></secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>getzonerootbyid</function></secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>getzonerootbylabel</function></secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>getzonerootbyname</function></secondary>
</indexterm><para>These functions obtain label information from objects in zones. The following routine descriptions include the prototype declaration for each routine:</para><variablelist termlength="wholeline"><varlistentry><term><literal>char *getpathbylabel(const char *path, char *resolved_path, size_t bufsize, const m_label_t *sl);</literal></term><listitem><para>The <function>getpathbylabel</function> routine expands all symbolic links and resolves references to <filename>/./</filename>, <filename>/../</filename>, removes extra slash (<literal>/</literal>) characters, and stores the zone path name in the buffer named by <replaceable>resolved_path</replaceable>. The <replaceable>bufsize</replaceable> variable specifies the size in bytes of this buffer. The resulting path does not have any symbolic link components or any <filename>/./</filename>, <filename>/../</filename>. This function can only be called from the global zone.</para><para>The zone path name is relative to the sensitivity label, <replaceable>sl</replaceable>. To specify a sensitivity label for a zone name that does not exist, the process must assert either the <constant>priv_file_upgrade_sl</constant> or the <constant>priv_file_downgrade_sl</constant> privilege, depending on whether the specified sensitivity label dominates or does not dominate the process sensitivity label.</para><para>See the <olink targetdoc="refman" targetptr="getpathbylabel-3tsol" remap="external"><citerefentry><refentrytitle>getpathbylabel</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man page.</para>
</listitem>
</varlistentry><varlistentry><term><literal>m_label_t *getzoneidbylabel(const m_label_t *label);</literal></term><listitem><para>The <function>getzoneidbylabel</function> routine returns the zone ID of the zone whose label is <replaceable>label</replaceable>. This routine requires that the specified zone's state is at least <constant>ZONE_IS_READY</constant>. The zone of the calling process must dominate the specified zone's label, or the calling process must be in the global zone.</para><para>See the <olink targetdoc="refman" targetptr="getzoneidbylabel-3tsol" remap="external"><citerefentry><refentrytitle>getzoneidbylabel</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man page.</para>
</listitem>
</varlistentry><varlistentry><term><literal>m_label_t *getzonelabelbyid(zoneid_t zoneid);</literal></term><listitem><para>The <function>getzonelabelbyid</function> routine returns the MAC label of <replaceable>zoneid</replaceable>. This routine requires that the specified zone's state is at least <constant>ZONE_IS_READY</constant>. The zone of the calling process must dominate the specified zone's label, or the calling process must be in the global zone.</para><para>See the <olink targetdoc="refman" targetptr="getzonelabelbyid-3tsol" remap="external"><citerefentry><refentrytitle>getzonelabelbyid</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man page.</para>
</listitem>
</varlistentry><varlistentry><term><literal>m_label_t *getzonelabelbyname(const char *zonename);</literal></term><listitem><para>The <function>getzonelabelbyname</function> routine returns the MAC label of the zone whose name is <replaceable>zonename</replaceable>. This routine requires that the specified zone's state is at least <constant>ZONE_IS_READY</constant>. The zone of the calling process must dominate the specified zone's label, or the calling process must be in the global zone.</para><para>See the <olink targetdoc="refman" targetptr="getzonelabelbyname-3tsol" remap="external"><citerefentry><refentrytitle>getzonelabelbyname</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man page.</para>
</listitem>
</varlistentry><varlistentry><term><literal>m_label_t *getzonerootbyid(zoneid_t zoneid);</literal></term><listitem><para>The <function>getzonerootbyid</function> routine returns the root path name of <replaceable>zoneid</replaceable>. This routine requires that the specified zone's state is at least <constant>ZONE_IS_READY</constant>. 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.</para><para>See the <olink targetdoc="refman" targetptr="getzonerootbyid-3tsol" remap="external"><citerefentry><refentrytitle>getzonerootbyid</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man page.</para>
</listitem>
</varlistentry><varlistentry><term><literal>m_label_t *getzonerootbylabel(const m_label_t *label);</literal></term><listitem><para>The <function>getzonerootbylabel</function> routine returns the root path name of the zone whose label is <replaceable>label</replaceable>. This routine requires that the specified zone's state is at least <constant>ZONE_IS_READY</constant>. 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.</para><para>See the <olink targetdoc="refman" targetptr="getzonerootbylabel-3tsol" remap="external"><citerefentry><refentrytitle>getzonerootbylabel</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man page.</para>
</listitem>
</varlistentry><varlistentry><term><literal>m_label_t *getzonerootbyname(const char *zonename);</literal></term><listitem><para>The <function>getzonerootbyname</function> routine returns the root path name of <replaceable>zonename</replaceable>. This routine requires that the specified zone's state is at least <constant>ZONE_IS_READY</constant>. 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.</para><para>See the <olink targetdoc="refman" targetptr="getzonerootbyname-3tsol" remap="external"><citerefentry><refentrytitle>getzonerootbyname</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man page.</para>
</listitem>
</varlistentry>
</variablelist>
</sect2><sect2 id="accessingnetworkdbentries"><title>Obtaining the Remote Host Type</title><indexterm><primary>remote host</primary><secondary>type</secondary>
</indexterm><indexterm><primary><function>tsol_getrhtype</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>tsol_getrhtype</function></secondary>
</indexterm><para>This routine determines the remote host type. The following routine description includes the prototype declaration:</para><variablelist termlength="wholeline"><varlistentry><term><literal>tsol_host_type_t tsol_getrhtype(char *hostname);</literal></term><listitem><para>The <function>tsol_getrhtype</function> routine queries the kernel-level network information to determine the host type that is associated with the specified host name. <replaceable>hostname</replaceable> 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 <structname>tsol_host_type_t</structname> structure. Currently, these types are <constant>UNLABELED</constant> and <constant>SUN_CIPSO</constant>.</para><para>See the <olink targetdoc="refman" targetptr="tsol-getrhtype-3tsol" remap="external"><citerefentry><refentrytitle>tsol_getrhtype</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man page.</para>
</listitem>
</varlistentry>
</variablelist>
</sect2><sect2 id="gdayc"><title>Translating Between Labels and Strings</title><para>The <function>label_to_str</function> and <function>str_to_label</function> routines are used to translate between labels and strings. The following routine descriptions include the prototype declaration for each routine:</para><variablelist termlength="wholeline"><varlistentry><term><literal>int label_to_str(const m_label_t *label, char **string, const m_label_str_t conversion_type, uint_t flags);</literal></term><listitem><para>The <function>label_to_str</function> routine translates a label, <structname>m_label_t</structname>, 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 <constant>sys_trans_label</constant> privilege.</para><para>See the <olink targetdoc="refman" targetptr="label-to-str-3tsol" remap="external"><citerefentry><refentrytitle>label_to_str</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man page.</para><para><indexterm><primary>library routines</primary><secondary><function>label_to_str</function></secondary></indexterm>The <function>label_to_str</function> routine allocates memory for the translated string. The caller must free this memory by calling the <function>free</function> routine.</para><para>See the <olink targetdoc="refman" targetptr="free-3c" remap="external"><citerefentry><refentrytitle>free</refentrytitle><manvolnum>3C</manvolnum></citerefentry></olink> man page.</para>
</listitem>
</varlistentry><varlistentry><term><literal>int str_to_label(const char *string, m_label_t **label, const m_label_type_t label_type, uint_t flags, int *error);</literal></term><listitem><para><indexterm><primary>library routines</primary><secondary><function>str_to_label</function></secondary></indexterm>The <function>str_to_label</function> routine translates a label string to a label, <structname>m_label_t</structname>. When you allocate an <structname>m_label_t</structname> structure, you must free the allocated memory by using the <function>m_label_free</function> routine.</para><para>When you create a label by using the <function>str_to_label</function> routine, you can set the label type to be a sensitivity label or a clearance label.</para><para>See the <olink targetdoc="refman" targetptr="str-to-label-3tsol" remap="external"><citerefentry><refentrytitle>str_to_label</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> and <olink targetdoc="refman" targetptr="m-label-3tsol" remap="external"><citerefentry><refentrytitle>m_label</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man pages.</para>
</listitem>
</varlistentry>
</variablelist><sect3 id="labelapi-28"><title>Readable Versions of Labels</title><para><indexterm><primary>library routines</primary><secondary><function>label_to_str</function></secondary></indexterm>The <function>label_to_str</function> routine provides readable versions of labels. The <constant>M_LABEL</constant> conversion type returns a string that is classified at that label. The <constant>M_INTERNAL</constant> 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.</para><itemizedlist><para>The <constant>conversion_type</constant> parameter controls the type of label conversion. The following are valid values for <constant>conversion_type</constant>, although not all types of conversion are valid for both level types:</para><listitem><para><constant>M_LABEL</constant> 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 <constant>M_LABEL</constant> string such as <constant>CONFIDENTIAL</constant> is not safe for storing in a public directory because the words in the label are often classified.</para>
</listitem><listitem><para><constant>M_INTERNAL</constant> is a string of an unclassified representation of the label. This string is safe for storing in a public object. For example, an <constant>M_INTERNAL</constant> string such as <literal>0x0002-04-48</literal> is safe for storing in an LDAP database.</para>
</listitem><listitem><para><constant>M_COLOR</constant> 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 <constant>LOCAL DEFINITIONS</constant> section of the <filename>label_encodings</filename> file.</para>
</listitem><listitem><para><constant>PRINTER_TOP_BOTTOM</constant> is a string used as the top and the bottom label of banner and trailer pages.</para>
</listitem><listitem><para><constant>PRINTER_LABEL</constant> is a string used as the downgrade warning on the banner page.</para>
</listitem><listitem><para><constant>PRINTER_CAVEATS</constant> is a string used in the caveats section on the banner page.</para>
</listitem><listitem><para><constant>PRINTER_CHANNEL</constant> is a string used as the handling channels on the banner page.</para>
</listitem>
</itemizedlist>
</sect3><sect3 id="labelapi-41"><title>Label Encodings File</title><para><indexterm><primary>library routines</primary><secondary><function>label_to_str</function></secondary></indexterm>The <function>label_to_str</function> routine uses the label definitions in the <filename>label_encodings</filename> 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 <filename>/etc/security/tsol/label_encodings</filename>. For information about the  <filename>label_encodings</filename> file, see <olink targetdoc="trsollbladmin" remap="external"><citetitle remap="book">Solaris Trusted Extensions Label Administration</citetitle></olink>, <olink targetdoc="wslblencode" remap="external"><citetitle remap="book">Compartmented Mode Workstation Labeling: Encodings Format</citetitle></olink>, and the <olink targetdoc="refman" targetptr="label-encodings-4" remap="external"><citerefentry><refentrytitle>label_encodings</refentrytitle><manvolnum>4</manvolnum></citerefentry></olink> man page.</para>
</sect3>
</sect2><sect2 id="labelapi-38"><title>Comparing Labels</title><indexterm><primary><function>bldominates</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary><function>blequal</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary><function>blstrictdom</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary><function>blinrange</function> routine</primary><secondary>declaration</secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>bldominates</function></secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>blequal</function></secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>blstrictdom</function></secondary>
</indexterm><indexterm><primary>library routines</primary><secondary><function>blinrange</function></secondary>
</indexterm><para>The <function>blequal</function>, <function>bldominates</function>, and <function>blstrictdom</function> routines are used to compare labels. The <function>blinrange</function> routine is used to determine whether a label is within a specified label range. In these routines, a <emphasis>level</emphasis> refers to a classification and a set of compartments in a sensitivity label or in a clearance label.</para><variablelist termlength="wholeline"><varlistentry><term><literal>int blequal(const blevel_t *level1, const blevel_t *level2);</literal></term><listitem><para>The <function>blequal</function> routine compares two labels to determine whether <replaceable>level1</replaceable> equals <replaceable>level2</replaceable>.</para>
</listitem>
</varlistentry><varlistentry><term><literal>int bldominates(const m_label_t *level1, const m_label_t *level2);</literal></term><listitem><para>The <function>bldominates</function> routine compares two labels to determine whether <replaceable>level1</replaceable> dominates <replaceable>level2</replaceable>.</para>
</listitem>
</varlistentry><varlistentry><term><literal>int blstrictdom(const m_label_t *level1, const m_label_t *level2);</literal></term><listitem><para>The <function>blstrictdom</function> routine compares two labels to determine whether <replaceable>level1</replaceable> strictly dominates <replaceable>level2</replaceable>.</para>
</listitem>
</varlistentry><varlistentry><term><literal>int blinrange(const m_label_t *level, const brange_t *range);</literal></term><listitem><para><indexterm><primary><function>blinrange</function> routine</primary><secondary>declaration</secondary></indexterm><indexterm><primary>library routines</primary><secondary><function>blinrange</function></secondary></indexterm>The <function>blinrange</function> routine determines whether the label, <replaceable>level</replaceable>, is within the specified range, <replaceable>range</replaceable>.</para>
</listitem>
</varlistentry>
</variablelist><para>These routines return a nonzero value when the comparison is true and a value of <literal>0</literal> when the comparison is false. For more information about these routines, see the <olink targetdoc="refman" targetptr="blcompare-3tsol" remap="external"><citerefentry><refentrytitle>blcompare</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man page. For examples of how these routines are used in the multilevel printing application, see <olink targetptr="labelprint-15" remap="internal">Validating the Label Request Against the Printer's Label Range</olink>.</para><para>For more information about label relationships, see <olink targetptr="labelrelationships" remap="internal">Label Relationships</olink>.</para><para><indexterm><primary><function>blminimum</function> routine</primary><secondary>declaration</secondary></indexterm><indexterm><primary><function>blmaximum</function> routine</primary><secondary>declaration</secondary></indexterm><indexterm><primary>library routines</primary><secondary><function>blmaximum</function></secondary></indexterm><indexterm><primary>library routines</primary><secondary><function>blminimum</function></secondary></indexterm>The <function>blmaximum</function> and <function>blminimum</function> routines are used to determine the upper and lower bounds of the specified label range.</para><variablelist termlength="wholeline"><varlistentry><term><literal>void blmaximum(m_label_t *maximum_label, const m_label_t *bounding_label);</literal></term><listitem><para>The <function>blmaximum</function> routine compares two labels to find the least upper bound of the range. The <firstterm>least upper bound</firstterm> is the lower of two clearances, which is used to determine whether you have access to a system of a particular clearance.</para><para>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.</para><para>See the <olink targetdoc="refman" targetptr="blminmax-3tsol" remap="external"><citerefentry><refentrytitle>blminmax</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man page.</para>
</listitem>
</varlistentry><varlistentry><term><literal>void blminimum(m_label_t *minimum_label, const m_label_t *bounding_label);</literal></term><listitem><para>The <function>blminimum</function> 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 <firstterm>greatest lower bound</firstterm> is the higher of two labels, which is also used to determine whether you have access to a system of a particular clearance.</para><para>See the <olink targetdoc="refman" targetptr="blminmax-3tsol" remap="external"><citerefentry><refentrytitle>blminmax</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man page.</para>
</listitem>
</varlistentry>
</variablelist>
</sect2>
</sect1><sect1 id="labelapi-31"><title>Acquiring a Sensitivity Label</title><indexterm><primary>labels</primary><secondary>acquiring</secondary>
</indexterm><indexterm><primary>labels</primary><secondary>user processes</secondary>
</indexterm><indexterm><primary>labels</primary><secondary>objects</secondary>
</indexterm><para>Sensitivity labels are acquired from labeled zones and from other processes. A user can start a process only at the current sensitivity label of the current zone.</para><para>When a process creates an object, the object inherits the sensitivity label of its calling process. You can use the <command>setlabel</command> command or the <function>setflabel</function> routine to set the sensitivity label of a file system object. See the <olink targetdoc="refman" targetptr="setlabel-1" remap="external"><citerefentry><refentrytitle>setlabel</refentrytitle><manvolnum>1</manvolnum></citerefentry></olink> and <olink targetdoc="refman" targetptr="setflabel-3tsol" remap="external"><citerefentry><refentrytitle>setflabel</refentrytitle><manvolnum>3TSOL</manvolnum></citerefentry></olink> man pages.</para><para>The following script, <command>runwlabel</command>, runs a program that you specify in the labeled zone that you specify. You must run this script from the global zone.</para><example><title><command>runwlabel</command> Script</title><para>The <command>runwlabel</command> script must first acquire the sensitivity label of the labeled zone in which you want to run the specified program. This script uses the <command>getzonepath</command> command to obtain the zone path from the label that you specify on the command line. See the <olink targetdoc="refman" targetptr="getzonepath-1" remap="external"><citerefentry><refentrytitle>getzonepath</refentrytitle><manvolnum>1</manvolnum></citerefentry></olink> man page.</para><para>Next, the <command>runwlabel</command> script uses the <command>zoneadm</command> command to find the zone name associated with the zone path, which was acquired by the <command>getzonepath</command> command. See the <olink targetdoc="refman" targetptr="zoneadm-1m" remap="external"><citerefentry><refentrytitle>zoneadm</refentrytitle><manvolnum>1M</manvolnum></citerefentry></olink> man page.</para><para>Finally, the <command>runwlabel</command> script uses the <command>zlogin</command> command to run the program that you specify in the zone associated with the label you specified. See the <olink targetdoc="refman" targetptr="zlogin-1" remap="external"><citerefentry><refentrytitle>zlogin</refentrytitle><manvolnum>1</manvolnum></citerefentry></olink> man page.</para><para>To run the <command>zonename</command> command in the zone associated with the <constant>Confidential: Internal Use Only</constant> label, run the <command>runwlabel</command> script from the global zone. For example:</para><screen>machine1% <userinput>runwlabel "Confidential : Internal Use Only" zonename</userinput></screen><para>The following shows the source of the <command>runwlabel</command> script:</para><programlisting>#!/sbin/sh
#
# Usage:
# runwlabel "my-label" my-program
#
[ ! -x /usr/sbin/zoneadm ] &amp;&amp; exit 0    # SUNWzoneu not installed

PATH=/usr/sbin:/usr/bin; export PATH

# Get the zone path associated with the "my-label" zone
# Remove the trailing "/root"
zonepath=`getzonepath "$1" | sed -e 's/\/root$//'`
progname="$2"

# Find the zone name that is associated with this zone path
for zone in `zoneadm list -pi | nawk -F: -v zonepath=${zonepath} '{
		if ($4 == zonepath) {
			print $2
		}
	}'`; do

		# Run the specified command in the matching zone
		zlogin ${zone} ${progname}
	done
exit</programlisting>
</example><para>The following script, <command>runinzone</command>, runs a program in a zone that you specify even if the zone is not booted. You must run this script from the global zone.</para><example><title><command>runinzone</command> Script</title><para>The script first boots the zone you specified, and then it uses the <command>zlogin</command> command to run the <command>waitforzone</command> script in the specified zone.</para><para>The <command>waitforzone</command> script waits for the local zone automounter to come up, and then it runs the program you specified as the user you specified.</para><para>To run the <command>/usr/bin/xclock</command> command in the <constant>public</constant> zone, run the following from the global zone:</para><screen>machine1% <userinput>runinzone public terry /usr/bin/xclock</userinput></screen><para>The following shows the source of the <command>runinzone</command> script:</para><programlisting>#!/sbin/ksh
zonename=$1
user=$2
program=$3

# Boot the specified zone
zoneadm -z ${zonename} boot

# Run the command in the specified zone
zlogin ${zonename} /bin/demo/waitforzone ${user} ${program} ${DISPLAY}</programlisting><para>The <command>runinzone</command> script calls the following script, <command>waitforzone</command>:</para><programlisting>#!/bin/ksh
user=$1
program=$2
display=$3

# Wait for the local zone automounter to come up
# by checking for the auto_home trigger being loaded

while [ ! -d /home/${user} ]; do
sleep 1
done

# Now, run the command you specified as the specified user

su - ${user} -c "${program} -display ${display}"</programlisting>
</example>
</sect1>
</chapter>