Trusted Solaris Developer's Guide

Chapter 6 Process Clearance

This chapter describes the programming interfaces for getting and managing the process clearance. The interfaces for reading user clearance information in the user_attr database are described in Chapter 9, Accessing User and Rights Profile Data.

Use of Process Clearance

When an application starts from the workspace, the user's session clearance is set on the process and called the process clearance. If the application forks a process, the new process's clearance is set to the calling process's clearance. If the application exec's a program the new program's clearance is set to the calling process's clearance.

The session clearance is selected at login. It sets the least upper bound at which the user can work during that login session and is dominated by the user clearance. The user clearance is assigned by the system administrator and determines the highest sensitivity label at which the user can work during any login session.

When users start applications from the workspace, the process CMW label is set from the values in the workspace CMW label. Because the process gets the session clearance and the workspace CMW label, the process clearance is always greater than or equal to the sensitivity label portion of the process CMW label. There is no privilege to change this rule.

A clearance has a classification and set of one or more compartments like the sensitivity label portion of a CMW label. A clearance is not a sensitivity label, but used in addition to the process's sensitivity label in the following ways.

Privileged Operations

The process needs proc_setclr privilege in its effective set to change its process clearance so it is not equal to its current clearance.

The process needs the sys_trans_label privilege in its effective set to translate a binary clearance to text when the process sensitivity label does not dominate the clearance to be translated. This privilege is also needed to check if a clearance is valid when the process sensitivity label does not dominate the clearance.

Data Types, Header Files, and Libraries

To use the programming interfaces described in this chapter, you need the following header file.


#include <tsol/label.h>

The examples in this chapter compile with the following library:


-ltsol

Process Clearances

Interfaces accept as parameters and return binary process clearances in a variable of type bclear_t.

Binary Levels

A level is a classification and a set of compartments in a sensitivity label or clearance. Interfaces accept as parameters and return binary levels in a structure of type blevel_t.

Type Compatibility

Any variable of type bclear_t or bslabel_t can be passed to a function that accepts a parameter of type blevel_t.

Programming Interface Declarations

The following programming interfaces are available for managing process clearances.

System Calls

These system calls get and set the clearance of the calling process. Refer to the getclearance(2) and setclearance(2) man pages.


Caution - Caution -

Every process that sets a clearance is responsible for setting a valid clearance as specified in the label_encodings(4) file, and must pass the correct binary form of the clearance. The text to binary translation functions correct the clearance as much as possible to ensure a correct binary clearance results from the translation. However, you might use the bclearvalid(3TSOL) routine to check that the clearance is valid.


int	getclearance(bclear_t *clearance);
int	setclearance(bclear_t *clearance);

Library Routines

Library routines are available to initialize, compare, translate and verify the process clearance.

Initialization

These routines initialize a clearance to ADMIN_HIGH, ADMIN_LOW, or undefined (similar to NULL). Refer to the blmanifest(3TSOL) man page.

void  bclearhigh(bclear_t *clearance);
void  bclearlow(bclear_t *clearance);
void  bclearundef(bclear_t *clearance);

Comparisons

These routines compare two levels to see if level1 equals, dominates, or strictly dominates level2. A level is a classification and set of compartments in a sensitivity label or clearance.

A returned non-zero is true and 0 is false. Refer to the blcompare(3TSOL) man page.

int  blequal(const blevel_t *level1, const blevel_t *level2);
int  bldominates(const blevel_t *level1, const blevel_t *level2);
int  blstrictdom(const blevel_t *level1, const blevel_t *level2);
int  blinrange(const blevel_t *level, const brange_t *range);

Clearance Type

The bltype(3TSOL) routine checks the clearance type, and the setbltype(3TSOL) routine sets the clearance type. A clearance can be defined or undefined. Refer to the bltype(3TSOL) man page.

int  bltype(const void *clearance, const unsigned char type);
void  setbltype(void *clearance, const unsigned char type);

Level Bounds

These routines compare two levels to find the sensitivity level that represents the greatest lower bound (blminimum(3TSOL)) or least upper bound (blmaximum(3TSOL)) of the range bounded by the two levels. A level is a classification and set of compartments in a sensitivity label or clearance. Refer to the blminmax(3TSOL) man page.

void  blmaximum(blevel_t *maximum_label,
				const blevel_t *bounding_label);
void  blminimum(blevel_t *minimum_label,
				const blevel_t *bounding_label);

Valid Clearance

This routine tests whether the specified clearance is valid for the system. Refer to the blvalid(3TSOL) man page.

int  bclearvalid(const bclear_t *clearance);

Binary and Text Translation

These routines translate a clearance from binary to text and back again. Refer to the stobl(3TSOL) man page.


Note -

See Chapter 14, Trusted X Window System for Interfaces that translate binary labels to text and clip the final label according to the specified width and font list for display in Motif-based graphical user interfaces (GUIs).


int  bcleartos(const bclear_t *clearance,
		char **string,
		const int len,
		const int flags);

int  stobclear(const char *string,
		bclear_t *clearance,
		const int flags, int *error);

char*  sbcleartos(const bclear_t *clearance,
		const int len);

Binary and Hexadecimal Translation

These routines translate a clearance from binary to hexadecimal and back again. Refer to the btohex(3TSOL) man page.

char  *h_alloc(const unsigned char id);
void  h_free(char *hex);

char  *bcleartoh_r(const bclear_t *clearance, char *hex);
char  *bcleartoh(const bclear_t *clearance);
int   htobclear(const char *s, bclear_t *clearance);

Process Clearance Operations

A program must get its process clearance before it can perform an operation on the clearance. This short program gets the process clearance of the calling process.

#include <tsol/label.h>

main()
{
	int          retval;
	bclear_t     pclear;

	retval = getclearance(&pclear);
	printf("Retval = %d\n", retval);
}

The printf statement prints the following:


Retval = 0

Set Process Clearance

The process needs the proc_setclr privilege to set the process clearance to another value if the new value is not equal to the sensitivity label portion of the process's own CMW label. A new process clearance is set with the setclearance(2) system call. This example initializes a clearance structure to ADMIN_HIGH and passes it to the setclearance(2) system call.

#include <tsol/label.h>

main()
{
	int          retval;
	bclear_t     hiclear, undef, loclear;

	bclearhigh(&hiclear);

/* Turn proc_setclr on in the effective set */
	retval = setclearance(&hiclear);
/* Turn off the proc_setclr privilege */

	printf("Retval = %d\n", retval);
}

The printf(1) statement prints the following:


Retval = 0

Initialize Clearance Structure

A clearance can be initialized to ADMIN_LOW or ADMIN_HIGH and have its type checked. This example initializes undef to undefined (similar to NULL) and loclear to ADMIN_LOW. It then checks the type on loclear, sets the type to undefined, and checks it again. A clearance is undefined when its ID field is initialized to SUN_CLR_UN. An undefined clearance is invalid. A clearance is defined when the ID field in the label structure is initialized to SUN_CLR_ID.

#include <tsol/label.h>

main()
{
	int          retval;
	bclear_t     loclear, undef;

	bclearlow(&loclear);
	bclearundef(&undef);

	retval = bltype(&loclear, SUN_CLR_ID);
	printf("Is clearance defined? %d\n", retval);

	setbltype(&loclear, SUN_CLR_UN);
	retval = bltype(&loclear, SUN_CLR_ID);
	printf("Is clearance defined? %d\n", retval);
}

The printf(1) statement prints the following where non-zero is True and 0 is False.


Is clearance defined? 1
Is clearance defined? 0

Find Relationships Between Two Levels

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

This example checks the process clearance against the sensitivity label portion of a file CMW label to find their relationship (equal, dominate, or strictly dominate). The process clearance is TOP SECRET A B, the sensitivity label portion of the file CMW label is Confidential.

#include <tsol/label.h>

main()
{
	int          retval;
	bclear_t     pclear;
	bclabel_t    cmwlabel;
	bslabel_t    senslabel;

	retval = getclearance(&pclear);
	retval = getcmwlabel("/export/home/zelda/afile", &cmwlabel);
	getcsl(&senslabel, &cmwlabel);

	retval = blequal(&pclear, &senslabel);
	printf("Clearance equals sensitivity label? %d\n", retval);

	retval = bldominates(&pclear, &senslabel);
	printf("Clearance dominates sensitivity label? %d\n", retval);

	retval = blstrictdom(&pclear, &senslabel);
	printf("Clearance strictly dominates sensitivity label? %d\n", retval);
}

The printf(1) statements print the following. Non-zero is True and 0 is False:


Clearance equals sensitivity label? 0
Clearance dominates sensitivity label? 1
Clearance strictly dominates sensitivity label? 1

Find Greatest Level and Lowest Level

The next example finds 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 (with the blminimum(3TSOL) routine) or least upper bound (with the blmaximum(3TSOL) routine) bounded by the two levels. A level can be a sensitivity label or clearance.

The example code finds the greatest lower bound and least upper bound of the range created by a process clearance of TS A B and a sensitivity label of ADMIN_LOW. The process runs at Confidential.

The first part of the example finds the greater of the classifications and the greater of all the compartments of the two levels 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 original parameter values passed.

The process sensitivity level does not dominate the process clearance so the process needs the sys_trans_label privilege for the translation. The code comments indicate where privilege bracketing as described in Chapter 3, Privileges should take place.

#include <tsol/label.h>
#include <tsol/priv.h>
main()
{
	int        retval, length = 0;
	char       *string = (char *)0, *string1 = (char *)0;
	bclear_t   clear;
	bslabel_t  senslabel;
	bsllow(&senslabel;);
	retval = getclearance(&clear;);
	blmaximum(&senslabel;, &clear;);
	/* Turn the sys_trans_label privilege on in the effective set */
	set_effective_priv(PRIV_ON, 1, PRIV_SYS_TRANS_LABEL); 
	retval = bsltos(&senslabel;, &string;, length, LONG_WORDS);
	printf("Maximum = %s\n", string);

The printf statements print the following where TS ABLE BAKER is the lowest level that dominates TS A B and ADMIN_LOW.


Maximum = TS A B

The second part of the example finds the lower of the classifications and only those compartments contained in both parameters, and puts that value in the first parameter. This operation finds the greatest lower bound because it finds the greatest level dominated by both original parameter values passed.

bsllow(&senslabel;);
blminimum(&senslabel;, &clear;);
retval = bsltos(&senslabel;, &string1;, length, LONG_WORDS);
printf("Minimum = %s\n", string1);
/* Turn sys_trans_label off */
set_effective_priv(PRIV_OFF, 1, PRIV_SYS_TRANS_LABEL);

}

The printf statements print the following where ADMIN_LOW is the highest level that is dominated by TS A B and ADMIN_LOW.


Minimum = ADMIN_LOW

Valid Clearance

A valid clearance is a clearance defined in the label_encodings(4) file. Call the bclearvalid(3TSOL) routine to check if a clearance is valid. The process running at TS A B equals the clearance and needs no privilege for this operation.

#include <tsol/label.h>
main()
{
	int          retval, error;
	bclear_t     bclear;
	char         *string = "TS ABLE BAKER";

	retval = stobclear(string, &bclear, NEW_LABEL, &error);
	retval = bclearvalid(&bclear);
	printf("Return value = %d\n", retval);
}

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


Return value = 1

Translating Process Clearances

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

Binary and Text

This example translate a binary clearance to text using long words. The process running at TS A B equals the clearance and needs no privilege.


Note -

The text input and output formats, rules, and flags are presented in "Binary and Text Label Translation".


#include <tsol/label.h>
main()
{
	int          retval, length = 0;
	bclear_t     pclear;
	char         *string = (char *)0;

	retval = getclearance(&pclear);
	retval = bcleartos(&pclear, &string, length, LONG_WORDS);
	printf("Process clearance = %s\n", string);
}

The printf(1) statement prints the following:


Process clearance = TS ABLE BAKER

This example clips the process label to five characters. The clipping occurs when the number of characters in pclear is greater than the specified length.

#include <tsol/label.h>

main()
{
	int          retval;
	bclear_t     pclear;
	char         *string = (char *)0;

	retval = getclearance(&pclear);
	string = sbcleartos(&pclear, 5);
	printf("Clipped process clearance = %s\n", string);
}

The printf statement prints the following. The left arrow is a clipped indicator to show the name has been clipped. The number of characters to which the name is clipped includes two characters for the clipped indicator.


Clipped process clearance = TS<-

This example translates a text string to a binary clearance.

#include <tsol/label.h>

main()
{
	int          retval, error;
	bclear_t     bclear;
	char         *labelstring = "TS ABLE BAKER";

	retval = stobclear(labelstring, &bclear, NEW_LABEL, &error);
	if (retval == 0)
		printf("Error = %d\n", error);
	else
		printf("Retval = %d\n", retval);
}

The printf(1) statement prints the following:


Retval = 1

Binary and Hexadecimal

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 clearance passed in is not type bclear_t.

Regular

This example translates the binary process clearance to hexadecimal and back.

#include <tsol/label.h>

main()
{
	int          retval;
	bclear_t     hclear;
	char         *string ;

	retval = getclearance(&hclear);

	if((string = bcleartoh(&hclear)) != 0)
		printf("Hex string = %s\n", string);

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

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


Hex string = 0xClearance hexadecimal value

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


Return Value = 1

Reentrant

The reentrant (MT-SAFE) routine bcleartoh_r(3TSOL) requires the allocation and freeing of memory for the value returned. The h_alloc(3TSOL) routine is used to allocate this memory, sizing it appropriately for the type of label (in this case hexadecimal) to be converted.

type where type is a hexadecimal value that indicates that a defined clearance (SUN_CLR_ID) is translated to hexadecimal.

This example allocates memory for the translation type, translates the binary process clearance to hexadecimal, and frees the memory at the end.

#include <tsol/label.h>

main()
{
	bclear_t     hclear;
	char         *string, *hex;

	getclearance(&hclear);
	hex = h_alloc(SUN_CLR_ID);
	if((string = bcleartoh_r(&hclear, hex)) != 0);
		printf("Hex string = %s\n", string);

	h_free(hex);
}

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


Hex string = 0x0006cc0000000000000000000000000000000000000 
000000003ffffffffffff0000