Program Statements
There are two types of program statements: executable and non-executable.
Executable program statements
Executable program statements allow security administrators to define and implement security rules. These types of statements have two major functions:
- Set the environment in which security profile files run
- Control the logic flow within security policy files
The following table summarizes the executable program statements:
Statement | Description |
---|---|
accept | Terminates security policy file processing and passes control to pblocald. |
assignment | Used to assign a value to a variable. |
break | Terminates the processing of cases within a loop and exits the loop. |
continue | Allows the remaining loop body to be skipped. Returns to the next iteration of the loop. |
do-while | Creates do-while loops which follow the C language syntax. |
for | C-style for. Used to create for loops which follow the C language syntax. |
for-in | Creates loops that execute the loop body for each element in an argument list. |
if | Determines which program statement to execute next based on whether an expression is true or false. |
include | Passes the flow of control to another file. |
readonly | Freezes the value of a variable so it cannot be changed by a security policy file. |
reject | Immediately terminates security policy file checking and cancels the current job request before it can execute. |
switch | Provides a way to execute a specific set of program statements based on an expression value. |
while | Builds while loops which follow the C language syntax. |
The Security Policy Scripting Language interpreter is case sensitive. Type the executable program statements in lowercase. For example, the word If is recognized as a variable name by the interpreter whereas the word if is recognized as an executable program statement.
Some general rules for creating program statements:
- Terminate program statements with a semicolon.
- A single statement can be multiple lines.
- Multiple statements can be included on one line if each statement terminates with a semicolon.
- Enclosing groups of program statements within curly brackets creates a compound statement. Each statement within the group must terminate with a semicolon.
Executable program statements have a special meaning to the Security Policy Scripting Language interpreter and cannot be used for other purposes. For instance, using an executable program statement as a variable name generates an error.
Many administrators desire a nonprogrammatic way of using EPM. To accomplish this goal, the policy language was extended to include an Access Control List structure. This structure extends the accept and reject statements to provide a simple nonprogrammatic way of specifying access data. It can be used exclusively to provide control, or it can be used in combination with the rest of the Endpoint Privilege Management for Unix and Linux policy language to provide greater control.
Note
For more information, see the following:
accept
Description
When an accept statement is encountered, security policy file processing terminates immediately, pblocald starts, and the secured task is executed by pblocald.
Syntax
All versions:
accept;
Version 5.0 and later:
accept [from ["user"][, ["submithost"][, ["command"]
[, ["runhost"]]]]] [when conditional-expression]
[with optional-statements-before-execution];
Definition
- user is a user name, list of user names, or left blank to imply any user.
- submithost is a submit host name, list of submit hosts, or left blank to imply any submit host.
- command is a command, list of commands, or left blank to imply any command.
- runhost is a run host, list of run hosts, or left blank to imply any run host.
- conditional-expression is an expression that evaluates true or false.
- optional-statements-before-execution is one or more Policy Language statements that executes before the requested command is executed. For multiple statements, separate each statement with a comma.
Example
if (user == "HelpDesk1") accept;
If user is equal to HelpDesk1, the task is accepted and allowed to execute. Security policy file processing immediately terminates. pblocald starts, and the information is sent from the policy server for pblocald to start the executable specified in the variable runcommand. It is run by pblocald with the arguments specified in the runargv variable and run as the user specified in the runuser variable. Other run variables can be set.
Example
Accept all commands for user1 from any submit host and for any run host:
accept from "user1";
Example
Accept all commands for user1 when the request comes from submit host host1 for any run host:
accept from "user1", "host1";
Example
Accept the date command from user1 from any submit host and for any run host:
accept from "user1",,"date";
Example
Accept all commands from user3, from any submit host and for any run host, when the time is between 9:00 A.M. and 5:00 P.M.:
accept from "user3" when timebetween(900, 1700);
Example
Accept a sh command from user1 or user3, from any submit host and for any run host, and turn on I/O logging:
accept from {"user1", "user3"},,"sh" with iolog = "/var/log/pb.iolog.sh";
Example
Accept all commands from all users, from any submit host and for any run host, when the time is between 9:00 A.M. and 5:00 P.M.:
accept when timebetween(900, 1700);
assignment
Description
An assignment statement assigns a value to a variable. An assignment can be used whenever an expression is expected, and multiple assignments can be done in a single statement.
Assignments are expressions and can be cascaded anywhere an expression occurs.
Syntax
list[n] = expression;
An expression can be a constant, variable, or complex equation.
var1 = var2 = var3 ... = value;
var1, var2, and var3 are assigned values.
Example
IntegerString = "1234";
StringList = {"User1", "User2", "User3"};
Counter = 1;
TotalUsers = 5;
CurrentUsers = 3;
InactiveUsers = TotalUsers - CurrentUsers;
userString = user;
runuser = "root";
list1 = {"a1", "a2", "a3"};
list2 = list1;
list2[0] = "l1"
The following occurs:
InactiveUsers is set to 2 (5 – 3)
userString = user; sets userString to the submitting user.
runuser = "root"; sets runuser to root.
list2[0] = "l1" causes list1 to still be {"a1", "a2", "a3"}, list2 has the value of
{"l1", "a2", "a3"}
Example
a = b = c = d = 0;
The variables a, b, c, and d are cascaded and assigned the same value (0).
break
Description
The break statement exits loops and terminates cases.
The break statement is used within loops and to end a clause in a switch statement.
Syntax
break;
Example
The statement prints the numbers between 1 through 5.
for (a = 1 ; a <= 10; a++) {
if (a > 5) break;
print (a);
}
continue
Description
The continue statement is used in the body of a C-style for, while, or do-while statement to skip the rest of statements in the body.
Syntax
continue;
Example
The statement prints the even numbers between 1 and 10.
for (a = 1 ; a <= 10; a++) {
if (a % 2 != 0) continue;
print (a);
}
C-style for
Description
The C-style for statement is used to execute a loop. The body which follows the for statement can be either a single statement or set of statements inside braces ( { and } ). This statement executes as follows:
- The start_expression is evaluated.
- The test_expression is evaluated.
- If the test_expression is false (0), execution ends.
- If the test_expression is true (non-zero), the body is executed.
- If a break statement is encountered in the body, the loop terminates.
- The step_expression is evaluated.
Repeat steps 2 through 6 until the test_expression is false, or a break statement is encountered.
If the test_expression is false the first time it is tested, then the step expression and body are not executed.
Syntax
for (start_expression; test_expression; step_expression ) body
Example
The statement prints the numbers from 1 to 5 until the test expression is false.
for (a=1; a <= 5; a+=1) print(a);
do-while
Description
The C-style do-while statement is used to execute a loop. The body that follows the while statement can be a single statement or set of statements inside braces ( { and } ). This statement is executed as follows:
- The body is executed.
- If a break statement is encountered in the body, the loop terminates.
- The test expression is evaluated.
- If the test expression is false (0), the loop terminates.
- If the test expression is true (non-zero), steps 1 through 4 are repeated until a break statement is encountered or the test expression becomes false.
The body is always executed at least once.
Syntax
do body while (test_expression);
Example
The statement prints the numbers 1 through 10.
a = 1;
do print(a++);
while (a <= 10);
for
Description
The for statement provides a mechanism to loop through or to repeat a series of program statements.
Syntax
for ControlValue = StartValue to StopValue [step Increment]
{executable program statements}
The for statement works in the following manner:
- The first time through the for statement, ControlValue is set to StartValue.
- ControlValue is immediately compared to StopValue.
- After an execution of the for statement has been completed and all associated program statements have been executed, StartValue is incremented by the step value.
- If a step value is not specified, a default step value of 1 is used. ControlValue is again compared to StopValue and the result of this comparison determines if the for statement executes again.
The comparison of ControlValue to StopValue works as follows:
- When the Increment value is positive, the for statement is executed as long as ControlValue <= StopValue evaluates to true.
- When the Increment value is negative, the for statement is executed as long as ControlValue >= StopValue evaluates to true.
- When the Increment value is 0, the for statement executes forever. An accept or reject is required to break out of the loop.
- If an Increment is not specified, 1 is used as the increment value.
Note
The for statement loop condition is tested at the top of the loop, and there is no guarantee the for loop will execute.
Example
In the for statement
for LoopCounter = 0 to 10 step 1
{counter = counter + 1;
counter2 = counter2 + 2;
}
The statement continues to loop as long as LoopCounter is less than or equal to 10.
Example
The for statement continues to loop as long as LoopCounter is greater than or equal to -5.
for LoopCounter = 0 to -5 step -1
{counter = counter + 1;
counter2 = counter2 + 2;
}
for-in
Description
The for-in statement is used to execute a loop for each element in a list. The body that follows the list can be either a single statement, or set of statements inside braces ( { and } ). This statement executes as follows:
- A variable is set to the first or next element of the list.
- The body executes. If a break statement is encountered in the body, the loop terminates.
- Steps 1 and 2 are repeated while there are elements left in the list or until a break statement is encountered.
When the loop is complete, the variable contains the last value assigned to it.
Syntax
for variable in list body;
Example
The statement prints each element in the list.
for name in {"one", "two", "three"}
print(name);
if
Description
The if statement is used to make a decision based on whether an expression evaluates to true or false. The decision determines what program statement is executed next. When expression evaluates to a non-zero value (true), the executable program statement immediately following the expression executes. When expression evaluates to 0 (false), the executable program statement immediately following the else statement is executed. When the chosen executable statement finishes, control flows to the next statement after the if statement. The else component of the if statement is optional.
Only one executable program statement can be inserted after the if expression or else statement. If multiple executable program statements are required, enclose them in curly braces {} to make a single compound statement.
Syntax
if (expression)
executable program statement;
else
executable program statement;
Example
# Make an accept or reject decision based on
# CurrentUserType
if (CurrentUserType == 1)
{
# if CurrentUserType is equal to 1, do these statements
RunCheck = true;
accept;
}else
{
# if CurrentUserType is not equal to 1, perform these statements:
RunCheck = false;
reject;
}
Note
For more information, see switch Statement.
include
Description
The include statement is very powerful. It enables a security policy file to embed another security policy file called a security policy subfile. When an include statement is encountered, the flow of control jumps to the included file. When the included file has completed execution, the flow of control returns to the statement immediately following the include statement in the original file. The following figure demonstrates this concept.
When specifying file-name, the specified file name must be either a string enclosed in quotation marks or a variable that contains a string. If a relative or absolute path is not specified, Endpoint Privilege Management for Unix and Linux looks for the file in the default security policy file directory. If a relative path name is specified, it is treated as relative to the security policy file directory that is specified in the policydir setting in pb.settings.
Note
Not supported in Endpoint Privilege Management for Linux (EPM-L).
Syntax
include file-name;
where file-name can be a variable containing a string or a string constant enclosed in quotation marks.
Example
include "/opt/pbul/policies/SupportStaffPolicies.conf";
include "/opt/pbul/policies/"+user+".conf";
Note
Use stat() to verify the existence of a file before adding an include statement that calls the file. Security policy subfile specifications that contain a variable may not be checked by pbcheck when checking the including file.
readonly
Description
The readonly statement freezes a variable. After a variable is marked as read only, a security policy file cannot change its value. In essence, the variable ceases to behave as a variable and becomes a constant.
The readonly statement has a global scope.
Syntax
readonly { "variable1" [, "variable2", …] };
Example
Do not allow changes to the following variables:
readonly { "CurrentUser", "CurrentCommand", "TargetHost" };
reject
Description
The reject statement immediately terminates security policy file checking and cancels the current job request without allowing it to execute. Depending on the parameters that are selected, the user sees a default message, custom reject message, or no message.
The policy language includes an Access Control List structure. This structure extends the accept statement to provide a simple nonprogrammatic way of entering access data.
Syntax
reject ["reject-text"] [from ["user"][, ["submithost"]
[, ["command"][, ["runhost"]]]]]
[when conditional-expression];
- reject-text is the text to display to the user.
- user is a user name, list of user names, or left blank to imply any user.
- submithost is a submit host name, list of submit hosts, or left blank to imply any submit host.
- command is a command, list of commands, or left blank to imply any command.
- runhost is a run host, list of run hosts, or left blank to imply any run host.
- conditional-expression is an expression that evaluates true or false.
reject statement display text
The reject statement has an optional reject-text expression in its argument. The meaning of the expression is as follows:
Name | Description |
---|---|
blank | Not specifying a parameter results in the display of the default request rejected by Policy Server… message. |
"" | An empty string suppresses the default request rejected by Policy Server… message. |
"string" | Replaces the default request rejected by Policy Server… message with a message specified by string. |
Example
Reject all commands from user4, from any submit host, and for any run host.
reject from "user4";
Example
Reject all commands, from any user and any submit host, and for any run host, when the time is between 5:00 P.M. and 9:00 A.M.
reject when timebetween (1700, 900);
Example
Reject all commands from user5 or user6, from any submit host, for run host host5, with the display message Permission denied.
reject "Permission denied" from {"user5", "user6"},,, "host5";
Note
For more information, see accept Statement.
switch
Description
The switch statement provides a way to execute a specific set of program statements based on an expression value. Each set of program statements has a value associated with them. A case statement represents this value. If the switch statement expression matches a case statement, then the logic that is associated with that case statement executes.
When a switch expression-case statement match is found, execution begins at the statement immediately following the case statement. Execution continues through each statement following the case statement until a break statement is encountered. The break statement forces an immediate exit from the switch statement.
When a break statement is encountered, execution immediately jumps to the first statement following the end of the switch statement. The break statement is optional.
If an expression / case statement match is not found, the logic associated with the default case executes. The default case is optional.
Note
The case labels must evaluate as strings.
Syntax
switch (string-expression)
{
case string1:
statement1a; [statement1b; …] [break;]
case string2:
statement2a; [statement2b; …] [break;]
default:
default-stmt1; [default-stmt2; …] [break;]
}
statement1a, statement1b, statement2a, statement2b, default-stmt1, and defaultstmt2 all represent executable program statements.
Example
Check to see if the current user name is valid. Valid users are admin and helpdesk. If the user is not valid, reject the request.
switch (user)
{
case "admin":
hostmachine = "AdminHost"; break;
case "helpdesk":
hostmachine = "HelpDeskHost";break;
default:
reject;
}
Note
For more information, see if Statement.
while
Description
The while statement is used to execute a loop. The body that follows the while statement can be a single statement or set of statements inside braces ( { and } ). This statement executes as follows:
- The test_expression is evaluated.
- If the test_expression is false (0), the loop terminates.
- If the test_expression is true (non-zero), the body executes.
- If a break statement is encountered in the body, the loop terminates.
Repeat steps 1 through 4 until the test_expression is false or a break statement is encountered.
If the test_expression is false the first time it is tested, the body is not executed.
Syntax
while (test_expression) body
Example
The statement prints the numbers 1 through 10 while a <=10.
a = 1;
while (a <= 10) {
print(a);
a += 1;
}
Non-Executable program statement
A non-executable program statement helps organize security policy files. Because non-executable program statements have a special meaning to the Security Policy Scripting Language interpreter, they are not used for any other purpose. For instance, using a non-executable program statement as a variable name generates an error.
The non-executable program statement consists of the Comment statement.
Comment statement
Description
Comment statements document the inner workings of individual security policy files. Comment text is nonexecutable code that is ignored by the interpreter during execution.
Comment statements must begin with the # character and continue to the end of the current line. No end character is necessary. This type of comment statement may not span multiple lines.
Syntax
# Comment text goes here.
Example
# This is a comment statement
Updated 12 days ago