Chat now with support
Chat with Support

Privilege Manager for Unix 6.1.1 - Administration Guide for Unix

One Identity Privileged Access Suite for Unix Introducing Privilege Manager for Unix Planning Deployment Installation and Configuration Upgrade Privilege Manager for Unix System Administration Managing Security Policy The Privilege Manager for Unix Security Policy Advanced Privilege Manager for Unix Configuration Administering Log and Keystroke Files InTrust Plug-in for Privilege Manager Troubleshooting Privilege Manager for Unix Policy File Components Privilege Manager Variables Privilege Manager for Unix Flow Control Statements Privilege Manager for Unix Built-in Functions and Procedures Privilege Manager programs Installation Packages

Example 7: Use variables to store constraints

Similar to Example 6, the fragment below defines a variable to store a set of constraints (in this case, office hours) which may be used more than once in the configuration file. This saves you from typing the constraints each time you need to refer to them.

In the following example, there are two policies which depend on office hours. The first policy rejects Dan’s requests if they are made outside office hours. The second policy requires Robyn to type in her password if she makes a request outside regular office hours. Note that officehours is set to "true" if the time of the request falls between 8:00 a.m. and 5:00 p.m., Monday to Friday. It is "false" if it is not in that time frame.

officehours = timebetween(800, 1700) && 
   dayname !in {"Sat", "Sun"}; 
adminusers={"dan", "robyn"}; 
adminprogs={"ls", "hostname", "kill", "csh", "ksh", "pmreplay"}; 
if(user in adminusers && command in adminprogs) 
   { runuser="root"; 
      if(command in {"csh", "ksh"}) 
         { iolog=mktemp("/var/adm/pm." + user + "." 
               + command + ".XXXXXX"); 
            print("The command will be logged in:", iolog); 
   } 
# Note how compact the following fragments are compared to 
# example6.conf, referring to the "officehours" variable. 
   if(user=="dan" && !officehours) 
      { print ("Sorry, you can't do that outside office hours."); 
         reject; 
      } 
         if(user=="robyn" && !officehours) 
            if(!getuserpasswd(user)) 
               reject; 
         accept; 
      }

Type this fragment into the /etc/opt/quest/qpm4u/policy/pm.conf file, or copy it from the examples directory in the Privilege Manager distribution directory. Replace "dan" and "robyn" with users from your site. Check the configuration file for errors with pmcheck. Then try to run commands with pmrun. For more information about using pmcheck, see Example 1: Basics.

Example 8: Control the run-time environment

This example demonstrates how you can set up a particular job's run-time operating environment with Privilege Manager. Although the policy fragments shown below are arbitrary, you can use similar fragments to implement your own policies.

Type the following fragment into the /etc/opt/quest/qpm4u/policy/pm.conf file, or copy it from the examples directory in the Privilege Manager distribution directory. Replace "dan" and "robyn" with users from your site.

Do not type in the line numbers.

1 # Run-time example configuration file 
2    adminusers={"dan", "robyn"}; 
3    adminprogs={"ls", "hostname", "kill", "csh", "ksh", "echo"}; 
4    if(user in adminusers && command in adminprogs) { 
5       if(!(cwd=="/usr" || glob("/usr/*", cwd)) 
6          runcwd="/tmp"; 
7       if(argc > 2) 
8          runargv=range(argv, 0, 2); 
9    runuser="root"; 
10    rungroup="bin"; 
11    if(command!="hostname") 
12       runhost=submithost; 
13    keepenv("TERM", "DISPLAY", "HOME", "TZ", "PWD", "WINDOWID", "COLUMNS", "LINES"); 
14    setenv("PATH", "/usr/ucb:/bin:/usr/bin:/usr/local/bin:/usr/bin/X11:" + 
15    "/usr/X11/bin:/usr/etc:/etc:/usr/local/etc:/usr/sbin"); 
16    safeshells={"/bin/sh", "/bin/csh", "/bin/ksh"}; 
17    if(getenv("SHELL") in safeshells) 
18       setenv("SHELL", getenv("SHELL")); 
19    else 
20       setenv("SHELL", "/bin/sh"); 
21    runumask=022; 
22    runnice=-4; 
23    accept; 
24    }

The following describes the results of this example:

  • Lines 5, 6

    These lines designate in which directory the job will run. Line 5 checks the current working directory: if the cwd variable is /usr or if it glob-matches "/usr/*", the request will run under that directory. If not, the request will run in /tmp.

  • Lines 7, 8

    In this example, no more than two arguments are allowed to be specified to the requested command. The range function in line 8 returns all arguments and only the first three elements of the argv list (element 0, which is the command name; element 1, the first argument; and element 2, the second argument).

  • Line 9

    This line causes the request to run as root.

  • Line 10

    This line causes the request to run as the bin group.

  • Line 11, 12

    These lines specify that if the command is not hostname, run it on the machine from which the request was submitted. If the command is hostname, run it on whatever machine the user wishes. (By default, it will run on the machine from which the request was submitted; you can change this using the -h argument to pmrun.)

  • Line 13

    First, line 13 deletes all environment variables, except those specified in the keepenv list. Since you can use environment variables to exploit security holes in UNIX programs and shell scripts, be careful when specifying the environment variables for a request.

  • Line 14

    This line sets the PATH variable explicitly to include only safe directories. Note the use of the + operator to concatenate the values assigned to the PATH variable; + splits the values over two lines to avoid ugly end-of-line wrapping.

  • Line 15-19

    This fragment ensures that the SHELL variable is only set to a safe value. If the existing SHELL variable is already set to one of the values defined as "safe" in safeshells, then that value is used. If not, then the SHELL is set to /bin/sh.

    Note that getenv reads from the env variable; setenv and keepenv write to the runenv variable.

  • Line 20

    This line sets the command's umask value to 022: data files created by the command will have rw-r--r-- permissions, and directories will have rwxr-xr-x permissions. Since the command will run under the root account, root will own the files.

    Specify a leading zero when typing in umask values so they are interpreted as octal numbers.

  • Line 21

    The command will run with a nice value of -4, which gives it a high priority relative to other jobs on the system.

  • Line 22

    After setting up the job’s environment, the request is accepted and the job is run.

Check the configuration file for errors with pmcheck. For more information about using pmcheck, see Example 1: Basics.

Try running your favorite shell, for example:

# pmrun csh

In the shell, you can then enter env to list the environment variables, pwd to print the working directory in which your request ran, or umask to display the umask value.

Example 9: Switch and case statements

The following example illustrates how you can use the switch and case statements to implement complex policies. In this case, different users act as system administrators on different days of the week.

Type this fragment into the /etc/opt/quest/qpm4u/policy/pm.conf file, or copy it from the examples directory in the Privilege Manager distribution directory. Replace "dan", "robyn" and "cory" with users from your site.

adminprogs={"ls", "hostname", "kill", "csh", "ksh", "echo"}; 
if(command in adminprogs) { 
switch (dayname) { 
   case "Mon": true; 
   case "Wed": true; 
   case "Fri": adminusers={"dan", "robyn"}; 
      break; 
   case "Tue": true; 
   case "Thu": adminusers={"robyn", "cory"}; 
      break; 
   default: adminusers={}; 
} 
if (user in adminusers) { 
   runuser="root" 
   accept; 
}

When entering a switch statement, execution immediately jumps to the first case statement that matches the argument to switch (in this case, dayname). Execution proceeds from that point until a break statement or the end of the switch is reached. When a break statement is reached, execution jumps immediately to the end of the switch. If no case matches the argument to switch, execution jumps to the default statement.

Once execution has jumped to a case statement, it is unaffected by subsequent case statements. Only a break causes execution to jump to the end of the switch statement. If you omit a break, execution falls through to the next case statement.

Check the configuration file for errors with pmcheck. For more information about using pmcheck, see Example 1: Basics.

Log in as one of the adminusers to see if you can run requests with pmrun (it will depend on the current day). See switch for further details.

Example 10: Menus

This example shows you how to present the commands a user may access as root in a menu by implementing a menu system with four choices. If the user selects the first menu item, he is asked to correctly type in a password before Privilege Manager runs the adduser program. If the user selects menu items b, c or d, Privilege Manager runs the backup, file ownership or line printer administration programs.

If the user’s request is accepted and completes, Privilege Manager prints messages to the user’s screen specifying the requested command and user under which the command will run. If the user makes an invalid menu choice, Privilege Manager prints a warning message and rejects the request.

Type the following code fragment into the /etc/opt/quest/qpm4u/policy/pm.conf file, or copy it from the examples directory in the Privilege Manager distribution directory. Replace "dan", "robyn", and "cory" with users from your site.

if(command=="adminmenu") { 
   print("========= Admin Menu ========="); 
   print("a) Add users"); 
   print("b) Start a backup"); 
   print("c) Change ownership of a file"); 
   print("d) Fix line printer queues"); 
   choice=input("Please choose one: "); 

   switch(choice) { 
      case "a": 
      # Reject the request if the password "123456" is not entered 
      # correctly. The user is allowed only two chances to type 
      # the password correctly. The encrypted version of the 
      # password seen here was generated using "pmpasswd". 
      # If you store encrypted passwords in your config file, 
      # make sure you turn off read permission on the file so 
      # that no one can use a password cracking program to 
      # guess them. 
         if(!getstringpasswd("m9xxg7B4.v8Ck", 
               "Type in the adduser password: ", 2)) 
            reject; 
         runcommand="/usr/local/bin/adduser"; 
         runuser="root"; 
         break; 
      case "b": 
         runcommand="/usr/local/bin/dobackup"; 
         runuser="backup"; 
         break; 
      case "c": 
         runcommand="/etc/chown"; 
         runuser="root"; 
         break; 
      case "d": 
         runcommand="/usr/lib/lpadmin"; 
         runuser="root"; 
         break; 
      default: 
         printf("\"%s\" was not a valid choice.Sorry.\n", choice); 
      reject; 
} 
   print("** Command to be run :", runcommand); 
   print("** User to run command as :", runuser); 
   accept; 
   }

Check the configuration file for errors with pmcheck. For more information about using pmcheck, see Example 1: Basics.

To display the menu, enter:

# pmrun adminmenu

Select the first menu item. When Privilege Manager asks you for the password, type "123456". Privilege Manager accepts the request and attempts to run the job.

Since the commands in this example probably do not exist on your system, the job will fail. Try substituting your own commands in each of the menu items, and test the fragment again.

Related Documents