You can use two lists in parallel, with information from element X of one list relating to information from element Y in the other list. In this example, the command name is related to its full pathname. You can incorporate this technique when you require certain users to type in a password that is different for each user.
okcommands={"ls", "sort", "pmreplay"};
okpaths={"/bin/ls", "/bin/sort", "/usr/etc/pmreplay"};
i=search(okcommands,command);
if(i==-1) {
print("Invalid Command");
reject;
} else {
runcommand=okpaths[i];
accept;
}
If the search fails (is set to -1), it rejects the request. Otherwise, the runcommand variable is set to the permitted path and command, and it accepts the request.
One Identity recommends that you keep the following guidelines in mind when building your configuration file. Give careful thought to the environment in which the job will run.
-
The directory in which the job will run should be controlled by the runcwd variable.
By default, jobs run in the same directory from which they are submitted.
- The environment variables that you consider "safe":
- Use the keepenv function to keep the "safe" environment variables and remove all others.
- Variables such as TERM, DISPLAY, and TZ are useful to keep; the job can access and make use of their values.
- Variables such as SHELL, PATH, IFS or LD_LIBRARY_PATH can have unspecified effects if set improperly. To avoid problems, use keepenv to delete these variables; use setenv to set them to safe values.
- Explicitly set the environment variables:
- Use the setenv function to set these variables.
- Always set the PATH variable explicitly. Running shell scripts or programs with a non-standard PATH can allow users to substitute their own -- possibly malevolent -- programs to run in place of the ones that you intended. Well-written shell scripts set PATH themselves. Set it explicitly in the Privilege Manager for Unix policy.
-
The machine on which the job will run should be controlled by the runhost variable.
By default, jobs run on the machine from which they are submitted. To run a job on a different machine, use the -h option of the pmrun command. If you are concerned about where the job will run, explicitly set the runhost variable. See pmrun for details.
- The user ID under which the job will run:
- Users typically use Privilege Manager for Unix to run jobs as root, but may specify any account.
- The runuser variable contains the name of the user under which the job will run.
- If you do not set runuser explicitly, the job will run under the user ID that originally submitted it. This may be advantageous if you are using Privilege Manager for Unix as a substitute for ssh to control who can log into a particular machine.
- The groups in which the job will run:
- The rungroup variable stores the name of the job’s primary group, while the rungroups variable stores a complete list of all groups to which the job belongs.
- The default is all groups to which the user submitting the job belongs.
- The command that will be run:
When you set runcommand, Privilege Manager for Unix automatically sets the runargv[0] variable to the base name of the runcommand value. UNIX shells do the same thing when you run a command.
- The arguments for the request:
If the command is a shell script, or if you wish to cause the command to be run through a shell, be careful with the argument list. By adding semicolons into an argument, you can completely change the behavior of a command. For example, if you run this command:
csh -c 'ls /tmp'
which lists the files in /tmp, a malicious user might type:
csh -c 'ls /tmp;rm /*'
Ensure that your programs and/or scripts can handle strange arguments safely.
- The type of logging done for the request:
- Set the iolog variable to a unique pathname; later replay the session using pmreplay.
- A log noting that the request was either accepted, rejected, or completed is stored by default in /var/opt/quset/qpm4u/pmevents.db. For more information about logging, see Event logging.
You can split up the configuration file into separate parts to reduce clutter. Use the include statement to hand off control to a subsidiary configuration file. While in the subsidiary configuration file, if an accept or reject occurs, control never returns to the main file. However, if no accept or reject occurs, once the end of the subsidiary configuration file has been reached, control returns to the parent file for further processing. Control resumes immediately after the include statement.
When handing off control to a subsidiary configuration file whose contents are controlled by a questionable person, it may be desirable to fix certain Privilege Manager for Unix variable values so that they cannot be changed by the subsidiary file. Use the readonly statement for this purpose.
For example, you may have an Oracle database administrator, who needs to administer certain Oracle programs. Each of those programs is to run as the "oracle" user. You would like the database administrator to be able to grant or deny access to these programs and this account without your involvement, but you certainly do not want to give this person power over non-Oracle parts of the system.
The following configuration file fragment hands off control to a subsidiary configuration file called pmoracle.conf, and ensures that if an accept is done within this file, the job being accepted can only run as the oracle user.
oraclecmds = {"oradmin", "oraprint", "orainstall"};
if(command in oraclecmds){
runuser = "oracle";
readonly {"runuser"};
include "/etc/pmoracle.conf";
reject;
}
The argument passed to readonly is a list of variable names (here, we have only specified one variable).
Also, the reject statement after the include ensures that if the pmoracle.conf configuration file does not accept or reject the job, this fragment will explicitly reject it. Of course, if the pmoracle.conf file accepts the job, the reject in this fragment will never be reached.
You can give the database administrator access to edit the pmoracle.conf file by entering "pmrun pmoracle.conf" if you include the following fragment. It calls the secure pmvi text editor (supplied with Privilege Manager for Unix), which allows the user to edit the file whose name is given on the command line, but will not allow the user to read or write any other file, nor to run any subprocesses from within the editor.
The following example sets:
- the command to be run (/opt/quest/bin/pmvi)
- its arguments ("pmvi /etc/pmoracle.conf")
- the user it will run as ("root")
- and accepts the request
if(command == "pmoracle.conf" && user == "dba_login_name")
{
runcommand = "/opt/quest/bin/pmvi";
runargv = split("pmvi /etc/pmoracle.conf");
runuser = "root";
accept;
}
You may use the configuration file to send mail messages when certain actions occur. The following fragment sends mail to root whenever the adduser program runs:
if(command=="adduser") {
system("mail root",
"pm: adduser was run as root by " + user + "\n");
}