Trusted Solaris Developer's Guide

Chapter 5 Label Code Examples

This chapter presents example code showing how to use the programming interfaces discussed in Chapter 4, Labels.

Retrieving Version String

The components of sensitivity labels and clearances; and the handling caveats that appear on printer output are specified in a site-specific label_encodings(4) file. Some of the programming interfaces described in this chapter access these specifications in the label_encodings file, and therefore, their outputs vary depending on the label_encodings file in use for a particular site.

This example gets the version string of the label_encodings file accessed in some of the code examples in this chapter, and prints the version string to standard out.

#include <tsol/label.h>

main()
{
	int retval, length = 0;
	char *version = (char *)0;

	retval = labelvers(&version, length);
	if(retval > 0)
		printf("Version string = %s\n", version);
}

The printf statement prints the following:


Version string = TRUSTED SOLARIS MULTI-LABEL SAMPLE VERSION -
    5.5 00/07/19

Initialize Binary Labels and Check Types

These interfaces initialize a label to ADMIN_HIGH, ADMIN_LOW, and undefined. ADMIN_HIGH represents the highest possible classification number including all compartments and all markings. ADMIN_HIGH strictly dominates every other label in the system. Normal users cannot read or write files at ADMIN_HIGH.

ADMIN_LOW represents a classification of zero with no compartments. All users can read or execute files with a sensitivity label of ADMIN_LOW. No normal user can write files at ADMIN_LOW. Every other label in the system strictly dominates ADMIN_LOW. ADMIN_LOW is assigned to publicly accessible system files and commands.

Undefined is similar to NULL and represents an invalid label. A sensitivity label is undefined when the ID field is initialized to SUN_SL_UN. An undefined label is invalid. CMW labels do not have an undefined state, only the sensitivity portion has an undefined state.

A CMW label or sensitivity label, is defined when the ID field in the label structure is initialized to SUN_CMW_ID or SUN_SL_ID.

This example initializes a label to ADMIN_HIGH and ADMIN_LOW, and then and checks and prints the label type.

#include <tsol/label.h>

main()
{
	int retval;
	bslabel_t psenslabel;
	bclabel_t pCMWlabel;

/* initialize labels*/
	bclundef(&pCMWlabel);
	bslhigh(&psenslabel);

/* Check label types */
	retval = bltype(&psenslabel, SUN_SL_ID);
	printf("Is sensitivity label defined? %d\n", retval);
}

The printf statements print the following. Non-zero is True and 0 is False.


Is sensitivity label defined? 1

Get Process CMW Label

You can get the process CMW label and perform operations on it as a unit, or extract the sensitivity label portion and perform independent operations on it. This example gets the process CMW label, extracts the sensitivity label portion, translates the process CMW label to a text string, and prints the process CMW label.

#include <tsol/label.h>

main()
{
	int retval, length = 0;
	bclabel_t pCMWlabel;
	bslabel_t psenslabel;
	char *string;

/* Get process CMW label */
	retval = getcmwplabel(&pCMWlabel);

/* Get sensitivity label portion */
	getcsl(&psenslabel, &pCMWlabel);

/* Translate the process CMW label to text and print */
	retval = bcltos(&pCMWlabel, &string, length, LONG_CLASSIFICATION);
	printf("Process CMW label = %s\n", string);
}

The printf statement prints the following where ADMIN_LOW is the information label and [C] is the sensitivity label. This CMW label means the process is running at a sensitivity level of Confidential ([C]) with an information label of ADMIN_LOW. The CMW label is inherited from the workspace in which the program is run.


Process CMW label = ADMIN_LOW [C]

The text output depends on the flag parameter to bcltos(3TSOL) and specifications in label_encodings(4). See "Binary to Text Label Translation Routines" for information on flag parameter values.

Set SL Portion of Process CMW Label

This example gets the calling process's CMW label, and sets the sensitivity portion to TOP SECRET (upgrades the label). The altered CMW label is set on the privileged process. The calling process needs the proc_setsl privilege in its effective set to change its sensitivity label. The code comments indicate where privilege bracketing as described in Chapter 3, Privileges should occur. (Note that this example will work only if the process clearance dominates TOP SECRET.)

#include <tsol/label.h>

main()
{
	int retval, error, length = 0;
	bclabel_t pCMWlabel;
	bslabel_t psenslabel;
	char *string = "TOP SECRET",  *string1 = (char *)0;

/* Create new sensitivity value and set CMW label to the value */
	retval = stobsl(string, &psenslabel, NEW_LABEL, &error);
	setcsl(&pCMWlabel, &psenslabel);

/* Set process CMW label with new CMW label */
/* Turn proc_setsl on in the effective set */
	retval = setcmwplabel(&pCMWlabel, SETCL_SL);
 /* Turn proc_setsl off */

}

The printf statement prints the following where ADMIN_LOW is the information label and [TS] is the sensitivity label.


Process CMW label = ADMIN_LOW [TS]

The text output depends on the flag parameter to bcltos(3TSOL) and specifications in label_encodings(4). See "Binary to Text Label Translation Routines" for information on flag parameter values.

The SETCL_SL value passed to setcmwplabel(2) sets the sensitivity label portion of the CMW label.

Get File CMW Label

You can get a file CMW label and perform operations on it as a unit, or extract the SL portion and perform independent operations on the SL portion.

This example gets the file CMW label and extracts the sensitivity label portion. The fgetcmwlabel(2) and lgetcmwlabel(2) routines are used the same way, but operate on a file descriptor or symbolic link.

#include <tsol/label.h>

main()
{
	int retval, length = 0;
	bclabel_t fileCMWlabel;
 bslabel_t fsenslabel;
	char *string = (char *)0;

/* Get file CMW label */
	retval = getcmwlabel("/export/home/zelda/afile", &fileCMWlabel);

/* Get sensitivity label portion */
	getcsl(&fsenslabel, &fileCMWlabel);

/* Translate fileCMWlabel to text and print */
	retval = bcltos(&fileCMWlabel, &string, length, LONG_CLASSIFICATION);
	printf("File CMW label = %s\n", string);
}

File CMW label = [CONFIDENTIAL]

Set SL Portion of File CMW Label

In this example, the process is running at Confidential with a Top Secret clearance. The process upgrades the sensitivity label portion of a file's CMW label to Top Secret and needs the file_upgrade_sl privileges because a label upgrade is a task that always requires privilege. The code comments indicate where privilege bracketing as described in Chapter 3, Privileges should take place.

A process cannot upgrade an object's sensitivity label to a higher level than its own clearance. "Find Greatest Level and Lowest Level"" describes how to check the process clearance against a sensitivity label.

If the system administrator has configured the system in the /etc/system file to not show file names when a file's CMW label has been upgraded, the upgraded file in this example will not be visible to a user who logs in at Confidential and lists the directory. See "Query System Security Configuration" for information on querying the system variables.


Note -

In the character-coded to binary translation, a new label is created with the NEW_LABEL flag parameter. See "Text to Binary and Hexadecimal Label Translation Routines" for information on the text to binary label translation and the flag parameter.


The SETCL_SL value passed to the setcmwlabel(2) system call indicates that the sensitivity portion is to be set. The new sensitivity label must be in the containing file system's label range, and the required privileges must be effective.

#include <tsol/label.h>

main()
{
	int retval, error;
	bclabel_t fileCMWlabel;
	bslabel_t fsenslabel;
	char *string = "TOP SECRET", 
	  *string1 = "TOP SECRET";

/* Create new sensitivity label value */
/* Turn sys_trans_label on in the effective set */
	retval = stobsl(string, &fsenslabel, NEW_LABEL, &error);
/* Turn sys_trans_label off */

/* Set sensitivity label portion of CMW label to new value */
	setcsl(&fileCMWlabel, &fsenslabel);

/* Set file CMW label */
/* Turn file_upgrade_sl privilege on in the effective set */
	retval = setcmwlabel("/export/home/zelda/afile", 
	  &fileCMWlabel, SETCL_SL);
 /* Turn file_upgrade_sl off */
 }

Use getlabel(1) to check the change in the file label. Before the program above runs, the CMW label for afile is as follows:


phoenix%  getlabel afile
afile: [CONFIDENTIAL]

After the program runs, the CMW label is as follows. Be aware that if you use the getlabel(1) command at Confidential, you will need the sys_trans_label privilege to read the label on a Top Secret file.


phoenix%  getlabel afile
afile: [TOP SECRET]

File System Label Range

The file system label range specifies the upper and lower bounds to the sensitivity of data contained in the file system. The getcmwfsrange() and fgetcmwfsrange() system calls return a structure that contains the upper and lower bound of the file system sensitivity label range.

How to query the file system security attributes in the inode or in the vfstab_adjunct(4) is described in "Query File System Security Attributes" in Chapter 2, Getting Started.

The following sections describe two situations where a program might get the file system label range and test a sensitivity label against it before taking further action.

Test Range Before Changing File CMW Label

Before upgrading a file CMW label (as was done in the previous example), it is a good idea to test the file system label range to be sure the file's new sensitivity label is within the sensitivity label range of the file.

This example converts text strings to a new binary sensitivity label, gets the file system label range, and checks if the new sensitivity label is within the file system's label range.

#include <tsol/label.h>

main()
{
	int retval, error;
	bclabel_t fileCMWlabel;
	bslabel_t fsenslabel;
	brange_t range;
	char *string = "TOP SECRET";

/* Create new sensitivity label value */
	retval = stobsl(string, &fsenslabel, NEW_LABEL, &error);

/* Get file system label range */
	retval = getcmwfsrange("/export/home/zelda/afile", range);

/* Test new sensitivity label against label range */
	retval = blinrange(&fsenslabel, range);
	if(retval > 0)
		{/* Proceed with file CMW label upgrade. */}
}

Test Range before Routing Data to Device

Always check the label range on a device special file before using the Trusted Solaris interfaces to allocate a device and route input to the device. The input routed to the device should be within the label range of the device-special file.

Test Label Relationships

If your application accesses data at different sensitivity labels, you can perform checks in your code to be sure the process label has the correct relationship to the data label before you allow an access operation to take place. You check the sensitivity label to find out if access will be allowed by the system or if privilege is required to override access restrictions.

These examples show how to test two sensitivity labels for equality, dominance, and strict dominance. The Trusted Solaris environment checks the process clearance when the process changes the sensitivity label on any object or writes to an object of a higher sensitivity label. "Find Relationships Between Two Levels" describes how to test for the relationship between a clearance and a sensitivity label.

Find Relationship Between Two Levels

A level is a classification and set of compartments for a sensitivity label or clearance; and is represented by the data type blevel_t. Two levels can be equal, one can dominate the other, or one can strictly dominate the other.

This example tests the process sensitivity label against a file's sensitivity label. The code for getting the process and file CMW label and extracting the sensitivity label portion is not shown. See "Get Process CMW Label" and "Get File CMW Label" for example code to perform these operations.

In this example, the process sensitivity label is Confidential and the file sensitivity label is Confidential. The labels are equal, the process label dominates the file label, but does not strictly dominate the file label.

#include <tsol/label.h>

main()
{
	int equal, dominate, strictdom, retval;
	bslabel_t *plabel, *filelabel;
	bclabel_t fileCMWlabel, pCMWlabel;

/* Get file and process CMW labels */
	retval = getcmwlabel("/export/home/zelda/afile", &fileCMWlabel);
	retval = getcmwplabel(&pCMWlabel);

/* Get sensitivity labels */
	plabel = bcltosl(&plabel);
	filelabel = bcltosl(&filelabel);

/* Once have both labels, test for equality */
	equal = blequal(plabel, filelabel);
	printf("Process label equals file label? %d\n", equal);

/* Test for dominance */
	dominate = bldominates(plabel, filelabel);
	printf("Process label dominates file label? %d\n", dominate);

/* Test for strict dominance */
	strictdom = blstrictdom(plabel, filelabel);
	printf("Process label strictly dominates file label? %d\n", strictdom);
}

The printf statement prints the following where any value greater than zero is true and zero is false.


Process label equals file label? 1
Process label dominates file label? 1
Process label strictly dominates file label? 0

Accessing CMW Label Portions

The procedure "Get Process CMW Label" uses the getcsl(3TSOL) and setcsl(3TSOL) routines to get and set the sensitivity portion of a process and file CMW label. This example uses routines to return a pointer to the sensitivity label portion of a CMW label.

#include <tsol/label.h>

main()
{
	bslabel_t *senslabel;
	bclabel_t pCMWlabel;
	int retval;

	retval = getcmwplabel(pCMWlabel);

/* Get a pointer to the sensitivity label portion of cmwlabel */
	senslabel = bcltosl(&pCMWlabel);

}

Finding Binary Level Bounds

The next two examples find the greatest and lowest values between two variables of type blevel_t. These interfaces let you compare two levels to find the level that represents the greatest lower bound (blminimum(3TSOL) routine) or least upper bound (blmaximum(3TSOL) routine) bounded by the two levels. A level can be a sensitivity label or a clearance.

In the example, senslabel is ADMIN_LOW and plabel is Confidential. The code finds the greatest lower bound and least upper bound of the range created by these two levels. The first example finds the greater of the classifications and the greater of all the compartments of the two variables passed to the blmaximum() routine and puts that value into the first parameter. This operation is called finding the least upper bound because it finds the lowest level that dominates both the original parameter values passed to the routine.

#include <tsol/label.h>

main()
{
	int retval, length = 0;
	char *string = (char *)0, *string1 = (char *)0;
	bslabel_t senslabel, plabel;
	bclabel_t pCMWlabel;

/* Initialize a label to ADMIN_LOW */
	bsllow(&senslabel);

/* Get process sensitivity label */
	retval = getcmwplabel(&pCMWlabel);
	getcsl(&plabel, &pCMWlabel);

	blmaximum(&senslabel, &plabel);
	retval = bsltos(&senslabel, &string, length, LONG_WORDS);
	printf("Maximum = %s\n", string);

The printf statements print the following where Confidential is the lowest level that dominates Confidential and ADMIN_LOW.

Maximum = CONFIDENTIAL

This part of the example finds the lower of the classifications and the lower of only those compartments contained in both parameters passed to the blminimum() routine, and puts that value into the first parameter. This operation is called finding greatest lower bound because it finds the greatest level dominated by both of the original parameter values passed to the routine.

	bsllow(&senslabel);

	blminimum(&senslabel, &plabel);
	retval = bsltos(&senslabel, &string1, length, LONG_WORDS);
	printf("Minimum = %s\n", string1);
}

The printf statements print the following where ADMIN_LOW is the highest level dominated by ADMIN_LOW and Confidential.


Minimum = ADMIN_LOW

Check Accreditation Range

Use the blinset() routine to check whether a sensitivity label is within the system or user accreditation range. The system accreditation range is all the labels valid for the system including ADMIN_HIGH and ADMIN_LOW. The classification and compartments of all sensitivity labels processed by a system must dominate the minimum sensitivity label of the system accreditation range and be dominated by the maximum sensitivity label of the system accreditation range. The system administrator defines the system accreditation range in the label_encodings(4) file.

The user accreditation range is all the sensitivity labels valid for a user and never includes ADMIN_HIGH or ADMIN_LOW. The classification and compartments of all sensitivity labels assigned to a user must dominate the minimum sensitivity label of the system accreditation range and be dominated by the maximum sensitivity label of the system accreditation range. The system administrator assigns the sensitivity label range (user accreditation range) to users and roles through the administrative user interface.

In this example the sensitivity label is checked against the system accreditation range (id.type = SYSTEM_ACCREDITATION_RANGE) and user accreditation range (id.type = USER_ACCREDITATION_RANGE).

#include <tsol/label.h>

main()
{
	char *string = "CONFIDENTIAL", *string1 = "UNCLASSIFIED";
	int sysval, userval, error, retval;
	bslabel_t senslabel;
	set_id id;

	retval = stobsl(string, &senslabel, NEW_LABEL, &error);
	id.type = SYSTEM_ACCREDITATION_RANGE;
	sysval = blinset(&senslabel, &id);
	id.type = USER_ACCREDITATION_RANGE;
	userval = blinset(&senslabel, &id);

	printf("System Range? = %d User Range? %d\n", sysval, userval);
}

The printf statement prints the following where 1 indicates the sensitivity label is within range, and 0 indicates one of the following: the sensitivity label is not a valid label, not in the specified range, or the calling process's sensitivity label does not dominate the sensitivity label and the calling process does not have the sys_trans_label privilege in its effective set.


System Range? = 1 User Range? = 1

Validating Labels

A valid label is a label defined in the label_encodings file. You can use the bslvalid(3TSOL) routine to check if a sensitivity label is valid. The sensitivity label of the calling process must dominate the sensitivity label being checked or the calling process needs the sys_trans_label privilege in its effective set for this operation to succeed.

#include <tsol/label.h>

main()
{
	int retval, error;
	bslabel_t senslabel;

	char *string = "CONFIDENTIAL";

	retval = stobsl(string, &senslabel, NEW_LABEL, &error);
	retval = bslvalid(&senslabel);
	printf("Valid Sensitivity Label? = %d\n", retval);
}

The printf statement prints the following where 1 indicates the label is valid; -1 indicates the label_encodings file is inaccessible; and 0 indicates the label is not valid, or the process sensitivity label does not dominate the clearance and the process does not have the sys_trans_label privilege in its effective set:


Valid Sensitivity Label? = 1

Getting Character-Coded Color Names

This example uses the bltocolor(3TSOL) call to get the character-coded color name associated with a sensitivity label of a particular level. The character-coded color names are specified in the label_encodings(4) file.

This example inquires about the character-coded color name associated with Confidential sensitivity labels. The process is running at Confidential so no privileges are needed for the inquiry. The calling process needs the sys_trans_label privilege in its effective set to inquire about labels that dominate the current process's sensitivity label.

#include <tsol/label.h>

main()
{
	int retval, error;
	bslabel_t senslabel;
	char *string = "CONFIDENTIAL";
	char *string1;

	retval = stobsl(string, &senslabel, NEW_LABEL, &error);

	string1 = bltocolor(&senslabel);
	printf("Confidential label color = %s\n", string1);
}

The printf statement prints the following:


Confidential label color = BLUE

Label Encodings Information

The labelinfo(3TSOL) routine returns maximum length values as short integers for various character data fields from the label library. An application laying out a field that contains label information might use these lengths. The length values change depending on the actual contents of the label_encodings(4) file.

#include <tsol/label.h>
main()
{
	int retval;
	struct label_info info;

	retval = labelinfo(&info);
	printf("Max sensitivity label length = %d\n", info.slabel_len);
	printf("Max CMW label length = %d\n", info.clabel_len);
	printf("Max clearance length = %d\n", info.clear_len);
	printf("Max version string length = %d\n", info.vers_len);
	printf("Max banner and trailer string length = %d\n", info.header_len);
	printf("Max protect as section string length = %d\n",
		info.protect_as_len);
	printf("Max caveats section string length = %d\n", info.caveats_len);
	printf("Max handling channels string length = %d\n", info.channels_len);
}

The printf statements print the following lengths:


Max sensitivity label length = 45
Max CMW label length = 259
Max clearance length = 76
Max Version String length = 56
Max Banner and trailer page string length = 13
Max Protect as section string length = 256
Max Caveats section string length = 62
Max Handling channels section string length = 81

Translating Labels

All labels can be represented in binary, text, or hexadecimal. Within the kernel all labels are stored in binary form, and binary is the form used for labels passed to and received from programming interfaces.


Note -

If label names are stored in files at a sensitivity label lower than the sensitivity level of the label names, or in files where users without the proper permissions or authorization could access them, store the label names in either binary or hexadecimal format to make them unreadable.


Binary and Text Label Translation

Labels can be translated from binary to text and back again. The calling process needs the sys_trans_label privilege in its effective set to translate any label not dominated by the process's sensitivity label.

Binary to Text Label Translation Routines

These examples translate binary labels to text. The translation uses the keyword settings in label_encodings(4) and the flag parameter value. Not all flag values make sense for every label, although nothing stops you from using any flag with any type of label. The descriptions state the label type a flag is to be used with. Settings that apply to sensitivity labels also apply to CMW labels.


Note -

The label view process attribute described in "Get and Set Process Security Attribute Flags" contains the status of the label view.


CMW Labels

The text output form for CMW labels is as follows:

[SENSITIVITY LABEL]

This example initializes a CMW label to ADMIN_LOW [ADMIN_HIGH] and prints out the internal and external views. The process runs at ADMIN_HIGH and does not need privileges to translate the ADMIN_LOW [ADMIN_HIGH] label.

#include <tsol/label.h>

main()
{
	int retval, length = 0;
	char *string1 = (char *)0, *string2 = (char *)0;
	bclabel_t cmwlabel;

	bclhigh(&cmwlabel);
	retval = bcltos(&cmwlabel, &string1, length, VIEW_INTERNAL);
	printf("View Internal = %s\n", string1);

	retval = bcltos(&cmwlabel, &string2, length, VIEW_EXTERNAL);
	printf("View External = %s\n", string2);
}

The printf statements print the following:


View Internal = ADMIN_LOW [ADMIN_HIGH]
View External = UNCLASSIFIED [TS A B SA SB CC]

Note -

Although bclhigh() and the other functions in the bclmanifest() family allow you to manipulate to manipulate the value of the information label of the CMW label, you cannot set this value on an object. The information label for all objects is ADMIN_LOW by default.


Sensitivity and Information Labels

The text forms of sensitivity labels and information labels output by interfaces are separated by spaces and formatted as follows where the curly brackets indicate optional items and the ellipses indicate repeated words. In a sensitivity label, words represent compartments, and in an information label words represent compartments and markings.

CLASSIFICATION {WORD}...

The following code example translates a binary sensitivity label to text using different flags. The process runs at TS A B and needs the sys_trans_label privilege for the translation after the call to bslhigh(3TSOL). The code comments indicate where privilege bracketing as described in Chapter 3, Privileges should take place.

#include <tsol/label.h>
main()
{
	int retval, length = 0;
	char *string1 = (char *)0, *string2 = (char *)0,
		*string3 = (char *)0, *string4 = (char *)0,
		*string5 = (char *)0, *string6 = (char *)0,
		*string7 = (char *)0;
	bclabel_t cmwlabel;
	bslabel_t senslabel;

	retval = getcmwplabel(&cmwlabel);
	getcsl(&senslabel, &cmwlabel);

	retval = bsltos(&senslabel, &string1, length, LONG_WORDS);
	printf("Retval1 = %d Long Words = %s\n", retval, string1);

	retval = bsltos(&senslabel, &string2, length, SHORT_WORDS);
	printf("Retval2 = %d Short Words = %s\n", retval, string2);

	retval = bsltos(&senslabel, &string3, length, LONG_CLASSIFICATION);
	printf("Retval3 = %d Long Classifications = %s\n", retval, string3);

	retval = bsltos(&senslabel, &string4, length, SHORT_CLASSIFICATION);
	printf("Retval4 = %d Short Classifications = %s\n", retval, string4);

	retval = bsltos(&senslabel, &string5, length, NO_CLASSIFICATION);
	printf("Retval5 = %d No Classification = %s\n", retval, string5);

	bslhigh(&senslabel);
/* Turn sys_trans_label on in the effective set */
	retval = bsltos(&senslabel, &string6, length, VIEW_INTERNAL);
/* sys_trans_label off. */
	printf("Retval6 = %d View Internal = %s\n", retval, string6);

	retval = bsltos(&senslabel, &string7, length, VIEW_EXTERNAL);
	printf("Retval7 = %d View External = %s\n", retval, string7);
}

The printf statements print the following.


Long Words = TS A B
Short Words = TS A B
Long Classifications = TOP SECRET A B
Short Classifications = TS A B
No Classification = A B
View Internal = ADMIN_HIGH
View External = TS A B SA SB CC

Text to Binary and Hexadecimal Label Translation Routines

This example translates text strings to a binary CMW label or sensitivity label using the following flag values:

CMW Labels

Text CMW labels are accepted in the following form: [sensitivity_label].

Sensitivity and Information Labels

Text sensitivity and information labels are accepted in the following forms. Input items can be separated by white space, commas, or slashes (/). Short and long forms of classification names and words are interchangeable.

{+} {classification} {{+|-}{word}...

Code Examples

This example translates text strings to a binary CMW label and sensitivity label and back again using the NEW_LABEL flag. An example of translating a sensitivity label to a specified length (clipping) is also given. If the process runs at [TS A B] or higher, the sys_trans_label privilege is not needed for the label translations.

#include <tsol/label.h>

main()
{
	int retval, error, length = 0;
	char *cmwstring ="SECRET A B [TOP SECRET A B]";
	char *sensstring = "TOP SECRET A B";
	char *string1 = (char *)0, *string2 = (char *)0,
		*string3 = (char *)0;
	bclabel_t cmwlabel;
	bslabel_t senslabel;


	retval = stobcl(cmwstring, &cmwlabel, NEW_LABEL, &error);
	retval = bcltos(&cmwlabel, &string1, length, ALL_ENTRIES);
	retval = stobsl(sensstring, &senslabel, NEW_LABEL, &error);
	retval = bsltos(&senslabel, &string2, length, ALL_ENTRIES);
	string3 = sbsltos(&senslabel, 4);

	printf("CMW label = %s\nSens label = %s\nClipped label = %s\n'',
		string1, string2, string3);
}

The printf statement prints the following. In the clipped label, the arrow <-indicates the sensitivity label name has clipped letters.


CMW label = [TS A B]
Sens label = TS A B
Clipped label = TS<-

Binary and Hexadecimal Label Translation

There are two types of binary to hexadecimal routines: regular and reentrant. Both types of routines return a pointer to a string that contains the result of the translation or NULL if the label being translated is not a binary label.

Binary and Hexadecimal Label Translation Routines

This example converts a binary CMW label to hexadecimal and back again. Converting a sensitivity label is similar.

#include <tsol/label.h>
#include <stdio.h>

main()
{
	int retval;
	bclabel_t hcmwlabel, hexcmw;
	char *string;

	getcmwplabel(&hcmwlabel);
	if((string = bcltoh(&hcmwlabel)) != NULL)
		printf("Hex string = %s\n", string);

	retval = htobcl(string, &hexcmw);
	printf("Return Value = %d\n", retval);
}

The first printf statements print the binary CMW label in the following hexadecimal format:

Hex string = ADMIN_LOW [0xsensitivity label value]

The second printf statement prints the following where non-zero indicates a successful translation:


Return Value = 1

Reentrant Binary and Hexadecimal Label Translation Routines

The reentrant (MT-SAFE) routine bcltoh_r(3TSOL) requires the allocation and freeing of memory for a variable of the specified type. This example allocates memory, translates the binary CMW label to hexadecimal, and frees the memory at the end. Converting a sensitivity label to hexadecimal and back is a similar process.

#include <tsol/label.h>
#include <stdio.h>

main()
{
	int retval;
	bclabel_t hcmwlabel, hexcmw;
	char *string, *hex;

	getcmwplabel(&hcmwlabel);
	hex = h_alloc(SUN_CMW_ID);
	if((string = bcltoh_r(&hcmwlabel, hex)) != NULL)
		printf("Hex string = %s\n", string);

	retval = htobcl(string, &hexcmw);
	printf("Return Value = %d\n", retval);
	h_free(hex);
}

The printf statement prints the binary clearance in the following hexadecimal format:


Hex string =0x00000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000[0x00040c0000000000000000000000
000000000000000000000003ffffffffffff0000]

Return Value = 1

Printer Banner Information

The bcltobanner(3TSOL) routine translates a binary CMW label into text coded labels and strings to appear on the printer banner page, trailer page, and document pages of print jobs. The labels and strings are computed from information in the label_encodings(4) file. This routine is used internally by the Trusted Solaris print system, and for most applications, this translation is unnecessary. However, it can be used in a print server application or in an application that needs the external character string representation used by the print system.

In this example, the CMW label is ADMIN_LOW [TS]. The first five fields of banner_fields are character pointers. If you preallocate memory for the character pointers, the second five fields contain short integer values indicating the length of the memory allocated. If you initialize the first five character pointers to (char *)0 as in the example, the short integer fields do not need initialization.

#include <tsol/label.h>
main()
{
	int retval;
	bclabel_t cmwlabel;

	static struct banner_fields banner = {(char *)0, (char *)0, (char *)0,
		(char *)0, (char *)0};

	getcmwplabel(&cmwlabel);

	retval = bcltobanner(&cmwlabel, &banner, SHORT_WORDS);

	printf("Top and bottom banner/trailer header = %s\n", banner.header);
	printf("Protect as section of banner page = %s\n", banner.protect_as);
	printf("Inf. label/top and bottom body pages = %s\n", banner.ilabel);
	printf("Caveats section of printer banner page = %s\n", banner.caveats);
	printf("Handling channels section of banner page = %s\n",
		banner.channels);
}

The text in the printf statement indicates where on the banner, trailer, and document pages the various strings appear. The caveats string is empty because no caveats are provided in the printer banner section of the label_encodings(4) file. See Trusted Solaris Label Administration and Compartmented Mode Workstation Labeling: Encodings Format for information on how the strings are computed.


Top and bottom banner/trailer header = TOP SECRET
Protect as section of banner page = TOP SECRET A B
Inf. label/top and bottom body pages = UNCLASSIFIED
Caveats section of printer banner page = 
Handling channels section of banner page = HANDLE 
         VIA (CH B)/(CH A) CHANNELS JOINTLY