Lesson 7 Sample: Policy optimizations
#=================================================================
# Privilege Manager for Unix example configuration file
# One Identity 2013
#
# Example File : example7
#
# This file should go in /etc/pm.conf with permissions of 600
# (rw-------).
# It must be owned by root.
#=================================================================
print("---------------- LESSON 7 DESCRIPTION -------------------");
os=osname();
printf("Policy file %s/examples/"+os+"/example7.conf\n",PMINST);
print("--------------------------------------------------------");
print("This lesson extends lesson 6 using variables to store
constraints");
print("which you might want to use several times in the policy file.");
print("Here, we set a variable to store whether or not it is currently");
print("within office hours or not. By storing it in a variable, we can
refer");
print("to it several times later on in the file if need be, without having");
print("enter and resolve the whole lengthly constraint each time.");
print("\nIn this example, there are two bits which we are interested in");
print("whether or not it is currently within office hours. The first bit is");
print("the same as in lesson 6, disallowing dan's requests outside of");
print("office hours. The second bit, near the end, requires the user");
print("to type in robyn's password if robyn makes a request outside of
normal");
print("office hours. This would be useful to protect against the situation");
print("where a user leaves a terminal logged in overnight.");
print("--------------------------------------------------------");
i=0;
while (i<argc)
   { printf("%s ",argv[i]); # Redisplay the original command line for clarity
      i=i+1;
   }
printf("\n");
#=================================================================
# Here, we set officehours to true if it is within office hours (8AM until 5PM
# Monday to Friday), false otherwise.
officehours = timebetween(800, 1700) && dayname !in {"Sat", "Sun"};
adminusers = {"dan", "robyn"};
adminprogs = {"ls", "hostname", "kill", "csh", "ksh"};
# Add the provided lesson user
adminusers=append(adminusers,PMLESSON_USER);
if (user in adminusers && command in adminprogs)
   { runuser = "root";
      if (command in {"csh", "ksh"})
         { iolog = mktemp("/var/adm/pm." + user + "." + command + ".XXXXXX");
            print("This command will be logged to:", iolog);
         }
      # Note how much more compact this is compared to example6.conf,
      # now that we can refer to the "officehours" variable.
      if (user == "dan" && !officehours)
         { print ("Sorry, you can't use that command outside office hours.");
         reject;
   }
   # Now we refer to "officehours" again. This time, if "robyn" is making
   # the request outside of office hours, robyn is asked to correctly
   # type in robyn's password. If it is not typed in correctly, the request
   # is rejected.
   if (user == "robyn" && !officehours)
      { if(!getuserpasswd(user)) reject;
      }
      accept;
}
#=================================================================
See Lesson 7: Policy optimizations for details on using this sample policy file.
 
    Lesson 8 Sample: Controlling the execution environment
#=================================================================
# Privilege Manager for Unix example configuration file
# One Identity 2013
#
# Example File : example8
#
# This file should have permissions of 600
# (rw-------).
# It must be owned by root.
#=================================================================
#=================================================================
# This example shows how facets of a job's run-time operating
# environment can be set up using Privilege Manager for Unix.
# Although the policies listed here are arbitrary, their structure
# can be used as examples or how to implement your own real policies.
# For experimental purposes, replace "dan" and "robyn" with user
# names from your own site.
adminusers = {"dan", "robyn"};
adminprogs = {"ls", "hostname", "kill", "csh", "ksh", "echo"};
if (user in adminusers && command in adminprogs) {
   # What directory should this job run in? For this example, we
   # want to say that if the job is executed from any directory
   # under /usr, it can be allowed to execute in that directory.
   # If it is not being executed from a directory under /usr, it
   # should execute in /tmp.
   if(cwd != "/usr" && !glob("/usr/*", cwd))
      runcwd = "/tmp";
   # Do not allow more than 2 arguments to be specified to the
   # command. The range function is used here to return only the
   # first 3 arguments of the argv list. The first element is the
   # command name, the second element is the first argument to
   # the command, and the third element is the second argument
   # to the command.
   if(argc > 2)
      runargv = range(argv, 0, 2);
   # Require the request to run as root.
   runuser = "root";
   # Require the request to run in the "bin" group.
   rungroup = "bin";
   # if the command being run is "hostname", run that command on
   # whatever machine the user requests (by default, the same
   # machine that pmrun is run from, but this can be changed
   # using pmrun's -h argument). Otherwise, requests should only
   # run on the same machine that the pmrun request was
   # submitted from.
   if(command != "hostname")
      runhost = submithost;
   # Since environment variables can sometimes be used to
   # exploit security holes in UNIX programs and shell scripts,
   # we should be careful to set up the job's environment
   # variables safely. We start by deleting any and all
   # environment variables except those specified in the
   # following list.
   keepenv("TERM", "DISPLAY", "HOME", "TZ", "PWD", "WINDOWID",
   "COLUMNS", "LINES");
   # Next we explicitly set up the PATH variable, so that only
   # safe directories are on it. Note the use of + to
   # concatenate the value that we want to assign to the PATH
   # variable. We use + so that we can split it up over 2 lines
   # to avoid ugly end-of-line wrapping.
   setenv("PATH",
   "/usr/ucb:/bin:/usr/bin:/usr/local/bin:/usr/bin/X11:" +
   "/usr/X11/bin:/usr/etc:/etc:/usr/local/etc:/usr/sbin");
   # We ensure that the SHELL variable is set safely. If the
   # existing SHELL variable is set to a safe value, which we
   # define as any of /bin/sh, /bin/csh, or /bin/ksh, then we
   # use that value. If not, then we use /bin/sh.
   # Note: getenv reads from the "env" variable, setenv and
   # keepenv write to the "runenv" variable.
   safeshells = {"/bin/sh", "/bin/csh", "/bin/ksh"};
   if(getenv("SHELL") in safeshells)
      setenv("SHELL", getenv("SHELL"));
   else
      setenv("SHELL", "/bin/sh");
   # Set the command's umask to 022 -- this means that data
   # files created by the command will have rw-r--r--
   # permissions, and executable files will have rwxr-xr-x
   # permissions. Since the command will run as root, root will
   # own the files. Note that we specify a leading zero when
   # typing in umask values, so that the values will be interpreted in
   # octal.
   runumask = 022;
   # The command should run with a "nice" value of -4, so that it
   # runs with a high priority relative to other jobs on the
   # system.
   runnice = -4;
accept;
}
#=================================================================
See Lesson 8: Controlling the execution environment for details on using this sample policy file.
 
    Lesson 9 Sample: Flow control
#=================================================================
# Privilege Manager for Unix example configuration file
# One Identity 2013
#
# Example File : example9
# This file should have permissions of 600
# (rw-------).
# It must be owned by root.
#=================================================================
#=================================================================
# This example shows how the switch and case statement can be used.
# In this case, we allow different users to act as system
# administrators on different days of the week.
# For experimental purposes, replace "dan", "cory", and "robyn" with
# user names from your own site.
adminprogs = {"ls", "hostname", "kill", "csh", "ksh", "echo"};
if (command in adminprogs) {
   switch (dayname) {
      case "Mon":
      case "Wed":
      case "Fri":
         adminusers = {"dan", "robyn"};
         break;
      case "Tue":
      case "Thu":
         adminusers = {"robyn", "cory"};
         break;
      default:
         adminusers = {};
   }
   if (user in adminusers) {
      runuser = "root";
         accept;
   }
}
#=================================================================
See Lesson 9: Flow control for details on using this sample policy file.
 
    Lesson 10 Sample: Basic menus
#=================================================================
# Privilege Manager for Unix example configuration file
# One Identity 2013
#
# Example File : example10
#
# This file should have permissions of 600
# (rw-------).
# It must be owned by root.
#=================================================================
#=================================================================
# This example shows how to implement a menu system with 4 choices.
# Also, if the "adduser" program is to be run, a password must be
# entered correctly.
# For experimental purposes, replace "dan", "cory", and "robyn" with
# user names from your own site.
if(command=="adminmenu") {
   print("========= Admin Menu =========");
   print("1) Add users");
   print("2) Start a backup");
   print("3) Change ownership of a file");
   print("4) Fix line printer queues");
   choice = input("Please choose one: ");
   switch(choice) {
   case "1":
      # Reject the request if the password "123456" is not entered
      # correctly. The user gets only 2 chances to type in the
      # password. 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 people cannot use password
      # cracking programs to guess them.
      if(!getstringpasswd("m9xxg7B4.v8Ck", "Type in the adduser password: ",2))
         reject;
      runcommand = "/usr/local/bin/adduser";
      runuser = "root";
      break;
   case "2":
      runcommand = "/usr/local/bin/dobackup";
      runuser = "backup";
      break;
   case "3":
      runcommand = "/usr/bin/chown";
      runuser = "root";
      break;
   case "4":
      runcommand = "/usr/lib/lpadmin";
      runuser = "root";
      break;
   default:
      printf("\"%s\" was not a valid choice. Sorry.\n", choice);
      reject;
}
if (choice == "3") {
   file_name=input("Please enter the new owner's name then file name: ");
   arguments = split(file_name);
   runargv = insert(arguments, 0, "Spacer");
}
   print("** Command to be run :", runcommand);
   print("** User to run command as :", runuser);
   accept;
}
#=================================================================
See Lesson 10: Basic menus for details on using this sample policy file.