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.
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.
When a process changes its sensitivity label, the process clearance determines the highest level to which the sensitivity label can be changed. A process cannot make its sensitivity label higher than its clearance. There is no privilege to change this rule.
When a process writes to an object at a higher sensitivity label (write-up), the process clearance determines the highest level to which the process may write up. A process cannot write above its own clearance.
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.
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 |
Interfaces accept as parameters and return binary process clearances in a variable of type bclear_t.
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.
Any variable of type bclear_t or bslabel_t can be passed to a function that accepts a parameter of type blevel_t.
The following programming interfaces are available for managing process clearances.
These system calls get and set the clearance of the calling process. Refer to the getclearance(2) and setclearance(2) man pages.
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 are available to initialize, compare, translate and verify the process clearance.
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);
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);
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);
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);
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);
These routines translate a clearance from binary to text and back again. Refer to the stobl(3TSOL) man page.
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);
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);
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 |
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 |
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 |
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.
Equal - One level is equal to another when its classification is arithmetically equal to the other's classification (by means of its place in the classifications hierarchy), and its compartments contain all the other's compartments and no additional compartments.
Dominates - One level dominates another when its classification is arithmetically greater than or equal to the other's (by means of its place in the classifications hierarchy), and its compartments contain all the other's compartments.
Strictly dominates - Level one is said to strictly dominate level two when level one dominates level two, but is not equal to level two.
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 |
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 |
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 |
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 Clearances - Classifications are stored as an integer and compartments are stored as bit vectors using 0's and 1's.
Text Clearance - Human-readable clearances that display classifications, and compartments using the names defined in the label_encodings(4) file.
Hexadecimal Clearances - The text representation of the hexadecimal number that represents the same bit pattern as the corresponding binary clearance. The clearance has text characters but does not reveal the classification or compartment names. A process can store a clearance in text when it will be read by processes at arbitrary clearances.
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.
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 |
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.
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 |
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 |