OP(1)                                                                    OP(1)

       op - grant operator access to certain commands

       op [-f file] [-g group] [-m label] [-u login] mnemonic [args]
       op -a|l|r|w [login]
       op -S [-n] [files]
       op -h
       op -H
       op -V

       System administrators grant trusted users certain privileged operations
       (or limited superuser access) via op, without giving them access to  an
       interactive  escalated  shell.  Different sets of users may access dif-
       ferent operations, and the security-related aspects of  environment  of
       each operation can be carefully controlled.

       Each  allowed  access is keyed on a short mnemonic which represents (to
       the client user) the operation desired.  For example,  start-apache  or
       stop-apache might by good mnemonics for local web server control.  That
       short-hand may expand to a complex shell command, or  may  simply  call
       the implied program (e.g. apachectl(8)) with forced arguments.

       If  you  are trying to use op to get access to an escalated command you
       should list the access you are allowed with:
              op -l | less
       From that list you may select any of the usage messages listed  to  use
       as  a  template  to  build your command.  The normal usage rules apply.
       That is: a pipe (|) lists alternatives, square brackets ([  ])  specify
       optionally  repeated  terms,  and  options  may have spaces between the
       specification or not.  If that doesn't display anything at  all  remove
       the "| less" and check for errors on stderr.

       If  you  need  to  know  why you have access to a rule but someone else
       doesn't you can ask with:
              op -w | less
       Read the phrase in brackets to see why you can access  each  rule.   If
       the  access is by "login name" then you'll have to get an administrator
       to change the rule-base.  If it refers to a  group,  then  see  if  the
       other  person  has a different set of groups, login group, or netgroups

       Here is an example which says I can run spoon with the -j or -k options
       and  a  single  parameter,  because  my primary login group allows that
       escalation (by name, not gid):
              op spoon -j|-k $2 [by login group name]

       To see what a rule might run try the -r option.  The administrator  may
       hide some rules by only showing something like:
              op $SHELL -c {script} $1 $2 [by anyone]
       or  output  may be just "Sorry".  Which might mean that the command has
       sensitive data in it, so they don't want to show it  to  you.   But  it
       doesn't mean the command shouldn't be trusted.

       -a [login]
              Output  all the rules login may access and their associated com-
              mands.  The rule is followed by the command, on the  next  line,
              indented with a tab.  See -l below for more details.

       -f file
              Specify  a file or directory for any mnemonic that requires one.
              That file may be used as part of  the  target  command-line,  or
              just  as part of the credential operation.  Of course the speci-
              fied file must match all  the  %f  and  !f  attributes  for  the
              selected rule.

       -g group
              Specify  a group for a mnemonic that uses %g, $g. or $G.  When a
              rule needs a -g option it must be specified, there is no default
              value.   The value specified must match any %g and !g attributes
              for the selected rule.

              Provide a brief help message.

              Provide a brief help message about our configuration  file  syn-
              tax.  Now includes a help for the expander macros (below).  This
              doesn't explain it all, but it sure helps a lot.

       -l [login]
              List all the rules available to the current login as they  might
              be expressed from the command-line.  Site policy may not a allow
              this option, in which case op  exits  with  EX_UNAVAILABLE,  see
              sysexits(3).   The  superuser  list  may include items commented
              with an octothorp (hash, #) which are rules that  are  forbidden
              to  the  superuser, but may be available to some others.  Mortal
              logins only see their allowed rules, while the superuser gets to
              see the output for any listed login.

       -m label
              Specify  a Mandatory Access Control label for the escalated pro-
              cess.  This is only  available  when  the  local  host  supports

              Do  not  consult  the existing rule-base for the sanity check we
              are about to run.  This is really useful to install  an  updated
              rule-base when the old one is not quite sane.

       -r [login] | -w [login]
              The  same  rules  are  displayed  as under -l, but op reports an
              approximation of the command template that will be  run.   Under
              -w  op  displays  which  credential  allows the access in square

       -S [files]
              Output a sanity report.  Various configuration options  and  the
              path  to  each  command are checked for lint errors.  A non-zero
              exit code indicated serious issues with the  configuration,  but
              some trivial errors only output a comment to stderr.  When files
              are specified they are added to the existing configuration,  and
              all checks are run as the original user.

       -u login
              Specify  a  login for a mnemonic that uses %u, $u or $U.  When a
              rule needs a -u option it must be specified on the command-line.
              The parameter may also be in the form login:group, in which case
              the suggested group is applied as if -g had  been,  but  doesn't
              prevent  execution  when  %g is not required, so it is otherwise
              ignored.   The  value  specified  must  match  any  %u  and   !u
              attributes for the selected rule.

              Provide  the  version of op installed as well as the path to the
              configuration file and any compile-time options set.

       The fields of the entries in access.cf are  separated  by  white-space.
       Each  entry  may  span  several  lines  and  continues  until  the next
       alphanumeric string is found at the beginning of a line (which is taken
       to  be the next mnemonic, and thus the beginning of a new entry).  Com-
       ments may be embedded beginning with an octothorp (hash, #)  character,
       ending at the end of line.

       Each  entry  in op's access.cf specifies a shell command to execute for
       the given mnemonic:
              mnemonic  command [args] ; [options]
       where the fields are interpreted in the following manner:

              an alphanumeric identifier for each operator function,  multiple
              entries for the same mnemonic in the same configuration file are
              differentiated by the number of arguments (via $# below), or  by
              matching  fixed  arguments  against  regular expressions (via $n
              below).  Since multiple configuration files may be processed  in
              an  arbitrary  order it is not clear which list may be processed
              first, so limit overloaded mnemonic entries  to  the  same  file
              (sanity checks this).

              The  full  pathname  of  the executable to be run by op when the
              associated mnemonic is selected or the string MAGIC_SHELL or  an
              open  curly  brace  ({) followed by an in-line shell script, see
              MAGIC SHELL below.  When  no  command  is  specified  we  assume
              /bin/sync, which is usually harmless.  This is actually a syntax
              error, but older versions of op allowed it.

              Any arguments to command, specified as either literal  words  or
              dollar pseudo-variables.  Literal arguments are simply specified
              directly, like specific command options  (Sh0Gun)  or  filenames
              (/dev/rmt20).   Variable  arguments  from  the  command-line are
              specified here as $1, $2 ... $n.   The  trailing  arguments  are
              given as $*, which includes only those beyond the highest number
              mentioned as $n, grouped into a single parameter.  Also $@  does
              the  same  thing,  but allows empty parameters and preserves the
              original word boundaries.   These  are  named  for  the  similar
              markup in the shell quotes ("$*" and "$@").  The number expanded
              by $# is the number of words in $@.  The  expander  $-  includes
              the  entire  mnemonic  request,  including the mnemonic name, as
              words.  The expander $+ formats the same data as a single  shell

       Other values are available see EXPANSION below.

              The  end of the args is usually a bare semicolon.  This not only
              delimits the arguments from the options (below), it  also  tells
              op  to execute the command in foreground.  The argument list may
              be terminated with an ampersand (&) to force the escalated  com-
              mand  to  run  in  background.  This really just sets the daemon
              option below.

              A set of optional specifications expressed as:
              Where appropriate values may actually be a list of specific val-
              ues separated by commas.  Since the assignments are separated by
              white-space, there may not be any  literal  white-space  in  any
              value.  Use markups to produce white-space (viz. $\s below for a
              space).  Also there is no need to quote parameters,  op  doesn't
              know about quotes at all.  If you put in quotes, you get literal

       The only special character is the dollar sign ($), see EXPANSION below.

       The sections below describe each keyword.

       One  of  these  three attributes must be matched to allow access to any

              Allow any user  listed  here  to  execute  this  mnemonic.   The
              default  is  not  allow  any  specific  users.   Use the regular
              expression ^.*$ to indicate that  all  users  may  use  a  given
              mnemonic.   A user may be matched by uid (user-id) with #RE. For
              example, to always match the superuser:

              Allow any user who belongs to a group listed  (by  RE)  here  to
              execute this mnemonic.  The default is not to allow any specific
              group.  A group may also be matched by gid (group-id) with  #RE.

              Allow  any  login  listed any specified netgroup to execute this
              mnemonic.  This is how one gets host specific access via  op  to
              an  mnemonic.  The hostnames never appear in the rule, rather we
              indirect through /etc/netgroup, which already knows about  host-
              names.    We  do  not  ever  specify  or  check  a  domain,  see
              innetgr(3).  Note that  the  netgroups  are  listed  as  literal
              names,  not as regular expressions.  The name dash (-) specifies
              a fictional empty netgroup group, used to override  any  default

       These attributes are used to match a command-line request to a rule:

              Limit  the  number  of  args  on the command-line to exactly the
              specified integer value.  This is one way to allow two mnemonics
              with  the  same name: when each has a different number of forced
              args then op knows which to select.  This is also the  best  way
              to limit the number of matches for $*.

              The  nth  command-line  argument specified must match one of the
              regular expressions listed.  If an argument does not  match  any
              of its permitted values, then then next mnemonic is tested for a
              match.  When none match a diagnostic is printed and  no  command
              is  executed.   A missing =REs is taken as "=.", which means the
              parameter may not be the empty string.

              The nth command-line argument specified cannot match any of  the
              regular expressions listed.

              When  the  the  command-line  arguments include a $n reject this

              Used in the options section to place restriction on the command-
              line  words  that are not matched by any $n.  Only try this rule
              when all of the (possibly many) command-line arguments match  at
              least  one  of  the  specified REs.  Note that each parameter is
              matched separately.

              If any of these (possibly many)  arguments  match,  then  reject
              this as a possible matching rule.

       The attributes below are used to make addition access checks.

              The  specified  PAM application must authenticate the requesting
              user before any  access  is  allowed.   This  option  skips  any
              password  check  when  satisfied.  The value dot (.) is taken as
              the default application listed  under  -V.   Unlike  some  other
              attributes, the empty value turns off PAM authentication.

              Queries  the  user for the password any of the given logins.  If
              there is no = part, or logins is dot (.) , then  the  requesting
              login's  own password is required.  Op allows %u for -u's user's
              password, and %f for the owner of the specified file's password.
              This check is skipped if the pam specification was satisfied.

              This  must  be an absolute path to a program that is safe to run
              with escalated privileges.  It is passed a large number of argu-
              ments  from  op, see API below.  The program does any additional
              authorization checks the site policy demands for the escalation,
              manifest  parameters  for  the  checks may be set as environment
              variables in the specification, as the environment  is  the  one
              proposed  for  the new process.  An exit code of zero allows the
              access requested with the  possibly  modified  environment,  see

              Like  a  helmet this co-process starts before the requested com-
              mand is executed with the same purpose and API as a helmet.  The
              new  command will be started when stdout is closed in the jacket
              process.  To obtain the exit code from the escalated command the
              jacket  must  then  wait  for  the child using the pid specified
              under -P (see API below).  The jacket might also time  the  com-
              mand,  restart  the command or log any additional aspects of the
              access required by local policy.  The exit code from the  jacket
              represents the success of the escalation.

       These attributes modify the new process's environment and privileges:

              Where  ENV  is  the  name  of an environment variable it will be
              assigned the specified value for the new process.

              The  specified  environment  is  inherited  unchanged  from  the
              caller's  shell.   Use  this with care, as some variables pose a
              substantial security risk.

              Disables the destruction of the user's environment.  Once  again
              use this with care.

              Passes  any  of the user's environment variable on that match at
              least 1 RE in the list.  This is used to allow access  to  ksb's
              wrappers.  Each RE is inspected for a literal equal sign (=), if
              it contains one then it is matched against the complete  string,
              else just the name of the variable.

              Set  the  user  id  to  the  value  specified.  The value can be
              numeric user ID or a login name.  The default  is  root  (really
              the  login  that owns the op binary).  The special value dot (.)
              is a macro for the real user id, this allows a task  to  be  run
              with the same uid, but a modified group list.  The special value
              percent-u (%u) requires a command-line -u option to specify  the
              login  name  at run-time.  The special value percent-f (%f) uses
              the owner of the file.   Local  site  policy  may  restrict  the
              logins available.

              Set the effective user id to be different from the uid.

              Add the groups listed to group access list.  Each value can be a
              numeric group ID or a group name.  The special value dot (.)  is
              taken  as  a  macro for the original real group id.  The special
              value percent-g (%g) requires a command-line -g option to  spec-
              ify  the  group  name  at run-time.  The special value percent-f
              (%f) requires a command-line -f option to specify a file to  set
              the  group  (by its group owner) at run-time.  The special value
              percent-u (%u) requires a command-line -u option to specify pri-
              mary  group  of  the run-time specified user.  Local site policy
              may restrict the groups available.

              Set the effective group id to  be  other  than  the  gid.   This
              accepts  any single specification as described under gid, above.

              Specify the addition of supplementary groups  for  this  command
              from  the  named  login  (e.g. initgroups=vanilla).  The special
              value dot (.) passes the current supplementary groups on,  which
              will  otherwise  be lost.  The special value percent-u (%u) uses
              the command-line user.  The special value  percent-f  (%f)  uses
              the  owner  of  the  file  to select a target login (using getp-
              wuid(3) to reverse map the uid to a login name).

              Set the groups from the uid option, or the euid option when that
              is not specified.  This is most useful as a DEFAULT option so as
              not to repeat the login specification from uid  on  every  rule.
              It  is  a  fatal error to specify an empty initgroups without an
              explicit uid (or euid) option.

              Setup a PAM session for the given login.  The login may also  be
              specified  as  %u  (under  -u), %i (the initgroups login, or its
              default value), %f (under -f), or original user (as .).   Unlike
              some  other  attributes,  the  empty value turns off PAM session

              Undo the work session did, at the cost of an additional process.
              To call pam_close_session(3) op must fork(2) a copy of itself to
              wait for the escalated process to exit.  The cleanup  specifica-
              tion  may  be any allowed for session, with the special form dot
              (.) interpreted to mean  "the  same  specification  as  session"
              (even  when session is empty).  As in the session specification,
              the empty value turns off PAM session cleanup.

              Change the current working directory to the path specified  (set

       stdin=path (also stdout, stderr)
              Force  the  input  (output, error) channel of the new process to
              the named path, or to the file as %f.  The  standard  shell  I/O
              redirection  markups  (<,  <>,  >, >>) are allowed to modify the
              open(2) flags.

              Specify your own argv[0] for the executed command.

              Change the root directory to the path specified using chroot(2).
              A  change  of  root  always  forces  a change of current working
              directory, when none is specified "/" is implied.

              Push the process into the background.  In this case stdin,  std-
              out,  and stderr of the process are all redirected to /dev/null,
              unless otherwise redirected.  Replacing the semicolon  separator
              between  the args and options with an ampersand (&) is a synonym
              for this option.

              Set the file creation umask to the octal value  specified.   The
              default is to set it to 022.

              Use  setpriority(2)  to change the integer nice value of the new
              process.  The value should be an integer from -20 to 20.

              Drops the log level of a successful escalation  from  NOTICE  to
              INFO.  See syslog(3), and Linux compatibility below.

              Use  setfib(2)  to change the network view to the specified one.
              This is only supported on FreeBSD at present.

       The attributes below match the command-line  values  of  the  -f  file,
       -u login, and -g group:

              Specify  a  list of regular expressions, one of which must match
              the named file attribute for the file specified under -f.

              Specify a list of regular expressions, none of which  may  match
              the named file attribute for the file specified under -f.

              For both of the above attr token may be any field from a stat(2)
              structure with the leading "st_"  removed.   In  that  case  the
              field  is  converted to a base-10 number for matching: dev, ino,
              nlink, atime, mtime, ctime, btime or birthtime,  size,  blksize,
              blocks, uid, gid.

              In  the  case of mode it is converted to a four-digit octal num-

              The token login (group) converts the uid (gid) to the login name
              (group name) via getpwuid(3) (getgrgid(3)).  The uid may also be
              matched by group membership (as %u@g  does)  with  login@g:  the
              reverse-mapped  uid  may  be  a  member of at least 1 group that
              matches one of the provided expressions.

              The token path matched the absolute path to the file.

              The token perms compares to a string as ls(1) would for the file
              permissions  (e.g.  drwxr-x---).   The  leading letter n notes a
              nonexistent file; others are taken from ls(1).

              The token access compares to a four character  string  based  on
              the  access(2) results against the invoking login's credentials:
              for example, "rwxf" when all access was allowed, "---f" when the
              file was not accessible, but the name was.

              The token type may have from 1 to 4 characters: the first is the
              same as the first of perms.  If the file is a symbolic link  the
              next  character  is  the  type-specifier for target of the link.
              Note that the special type n  indicates  a  symbolic  link  that
              (presently)  dangles.   If the target (of the link, or directly)
              is a directory, the letter m is added if  that  directory  is  a
              mount-point.   The next is an e if the type was d and the direc-
              tory is empty.  (So an link to  a  mounted  empty  directory  is
              ldme, and a nonexistent file is n.)

       %f=RE or !f=RE
              These shorthands default to the path attribute, above.

       %d.attr=REs or !d.attr=RE
              These allow parallel checks of the directory containing the file
              specified under -f, but do not count for all sanity checks.

       %_.attr=REs or !_.attr=RE
              These allow parallel checks for the file to  be  executed  ($_).
              Note that the built-in echo command doesn't exist, so it has the
              perms of "n---------".

              Specify a list of regular expressions, one of which  must  match
              the login (as a name) specified on the command-line.

              Specify  a list of regular expressions, when the login specified
              under -u matches any of these it is rejected as "black  listed".

              Specify  a  list of regular expressions, one of which must match
              the name of a group in which the login is explicitly listed as a

              Black list a login based on membership in any group that matches
              any of the listed regular expressions.

              Specify a list of regular expressions, one of which  must  match
              the group (as a name) specified on the command-line.

              Specify  a list of regular expressions, when the group specified
              under -g matches any of these it is rejected as "black  listed".

              Require  that  the  group  specified include a login matching at
              least one of the REs provided.  Three  special  expressions  are
              also  allowed:  %u  (match the login given under -u as login, %l
              (match the login name of the real uid), %e (match the login name
              of the effective uid).  Each of these are anchored to require an
              exact match.

              Blacklist any group with a member login that  matches  any  REs.
              The  same  special  expressions are allowed.  An offending group
              must be listed in the group file (/etc/group),  not  just  as  a
              primary login group.  See group(5).

              The  new  environment value (created by the $env=value option or
              allowed by either $env or the  environment  option's  REs)  must
              match at least one of the listed REs.

              The  new  environment value (as above) must not match any of the
              listed REs.  A failure to pass this restriction denies the esca-

       There  may  also  be a special entry in the file beginning at the first
       non-comment line to define default values, or to override the  built-in
       defaults listed here.  Such a declaration has the following format:
              DEFAULT   keyword_options
       where keyword_options is a list of keyword=value string mentioned above
       under options.

       Note that if any regular mnemonic entry defines its own value  for  any
       options,  then  any  value given for that entry must explicitly include
       the item from the  DEFAULT  line,  if  the  default  values  is  to  be
       included.   That  is to say the options definitions completely override
       any defaults; they do not add to them.  In this way a  value  specified
       on  the  DEFAULT  line  for users (for example) may be "erased" without
       defining new limit, by an explicit specification of the empty value:
       Such a null setting has the effect of setting  the  list  of  allowable
       users  or  groups to be unspecified.  For the other keywords (uid, gid,
       dir, and chroot), a null setting leaves that attribute as  it  is  upon
       invocation  of  the  op  program,  clearing any configuration specified
       default value.

       Each file may include a specific DEFAULT definition  which  applies  to
       all of the stanzas below it (in that file).  If the first definition in
       access.cf is a DEFAULT, then it applies to  any  stanza  which  doesn't
       have  a specific one for every configuration file.  Thus any audit of a
       rule-base must first establish that the default in access.cf is accept-

       Default  rules must never include $#, $1, !1, $2, or any other $integer
       attribute as these are checked without consulting the in-scope  DEFAULT
       rule.   Sanity  (under -S) complains bitterly if a such a rule violates
       this injunction.

       When the command for a mnemonic is the word MAGIC_SHELL  that  word  is
       discarded from the command, then op processes the positional parameters
       to build the new command from the args differently.

       First when the command has no other words  op  constructs  a  new  one.
       When there are positional parameters on the command-line it uses:
              $S -c $*
       When there are no command-line parameters is uses:
       If the SHELL specified for $S is perl(1), then the "-c" is changed to a
       "-e" in the positional parameter case.

       To form the target command op  then  consolidates  all  the  parameters
       above the last number specified in the args to into the last parameter.
       This allows the command to group them as a single argument to a  shell,
       or other application as $*.  Note that all sense of how they were orig-
       inally quoted is lost.

       The default shell is /bin/sh.   An  explicit  specification  of  $SHELL
       overrides  this.   The  users  $SHELL environment variable is consulted
       when environment set or when $SHELL mentioned to allow it to be read.

       An in-line script is similar to the above: in-place of command  in  the
       rule configuration a lone open curly ({) starts an in-line script.  The
       script ends at the first following line that begins with a close  curly
       (})  as  the  first  nonwhite-space character on the line.  The in-line
       script is replaced with the token sequence:
            $S -c $s
       where $s is  the  in-line  script  with  the  delimiting  curly  braces
       removed.   Any  parameters  after the script are taken as parameters to
       the in-line script by the shell.  The shell may be perl, in which  case
       the "-c" is replaced with "-e".

       Recall  that Bourne compatible shells take the first positional parame-
       ter after a -c script as $0 (the name of the script).  So  the  command
       below outputs "b":
            /bin/sh -c '{ echo $1 ; }' a b c d
       It  is therefore common to pad with $0 to force the mnemonic name to be
       the same in the shell code as well (also note that  a  single  dash  is
       taken  as  an  empty option list by the shell).  Since csh would output
       "a" for the above test, it is nuts to use csh(1) for anything.

       The use of in-line scripts should be a last resort: usually it  is  far
       better  to call a well documented program than to create ad-hoc scripts
       with little security review.  The magic shell and in-line script  forms
       are mutually exclusive.

       If  you  really want to run a program named MAGIC_SHELL then use a null
       string markup to prevent the comparison, as in "MAGIC$|_$|SHELL".

       One additional command is special to op: the word  "echo"  triggers  an
       internal  version  of  the echo(1) command, just like a shell provides.
       This built-in command is therefore exempt from any path  search  check-
       ing.   It  is  usually  used  in combination with the stdout keyword to
       change a flag file or append to a log file.

       The helmet and jacket processes are passed a very complete  description
       of  the  credentials  used to grant the proposed access as a UNIX shell
       command-line.  The usage for that command-line is:
              path [-P pid] [-u user] [-g group] [-f file] [-R root] -C config
              [-m mac] -- mnemonic program euid:egid cred_type:cred

       The options -u, -g, -f, and -m are only passed when they were specified
       on the op command-line.  This allows more checks on their values,  ones
       op  could  not  understand.  For example, being sure the target user is
       presently frozen in LDAP, has valid Kerberos context, or is running  an
       instance of ssh-agent(1) or screen(1).

       The  option  -R  root  is only presented when a chroot(2) is in effect.
       For a helmet if has not yet been applied, for a jacket it  has  already
       been applied, so we are in that limited environment.

       The  option  -P  is only presented to the jacket to tell it which child
       process is the key one (since any process might have children it didn't
       fork).   This  difference  allows the same program to be used as both a
       helmet and a jacket.

       The -C option will always be present to  tell  which  op  configuration
       file  included  the  proposed  command (config passes down $w).  If you
       want the line number of the definition set an environment  variable  to
       $W, then remove it with the environment API.

       mnemonic program
              These  give  the mnemonic the customer specified and the program
              op mapped that to.

              These are the proposed effective user-id and group-id  the  pro-
              cess  will have, the real user-id and group-id are not sent (for
              most sane application they are the same), but  any  setgroups(2)
              call  has  been  issued so the process may inspect its own group
              list, see getgroups(2).

              The cred_type is one of groups, users, or netgroups and the cred
              is  the  one that matched.  The test harness uses the type test,
              but op never does.

       A very simple command processor is reading  stdout  from  the  process.
       Six commands are available with each consuming a whole line of text:

       # comment
              Each  comment  is ignored, unless op was compiled with DEBUG, in
              which case they are output to stderr as an aid while tracing the
              actions of helmets and jackets.

              Preserve  the value of NAME from the original environment.  This
              doesn't work under the coat(7l) jacket if the value  is  require
              for  any  other  layered jacket checks, but does work to set the
              value in the escalated process.

              The given environment variable is set to  value  in  the  target
              process,  which  may include white-space.  This is a good way to
              get a multi-word value forced  into  the  environment,  as  op's
              lexical analyzer is strongly against quotes (or use $\s to inset
              any required spaces).  But there is no way to embed  an  newline
              in the value.

              Remove  the  string  PREFIX  from all environment variables cur-
              rently set.  This allows nested instances of some jackets.  That
              usage is uncommon, but very nifty.  See the "coat" jacket.

              Remove  the given environment variable from the target process's
              environment.  This is used to remove variables  passed  to  this
              process as parameters that we don't want to show the Customer.

       &0[<]path or &1[>][>]path or &2[>][>]path
              Force  a  new stdin for the escalated process.  Likewise 1 redi-
              rects stdout and 2 redirects stderr.  If the path  is  a  socket
              the open(2) fails then a connect(2) is tried.

              Any number above 2 closes all file descriptors above that number
              (inclusive).  The default is not to close extra channels.

              Set a non-zero (or zero if you like) forced exit(3) code.

       When a helmet process exits, its exit code is also checked for  a  non-
       zero  exitcode,  which tells op that the process failed to complete the
       check (so it rejects the access).

       In the case of a jacket process a  non-zero  exitcode  sent  to  stdout
       stops the access before the program is executed, and the exit code sent
       by the jacket is the exit code from the op process.

       A jacket process could even kill(2) the child process before it begins,
       but  that  would be poor form.  To force a graceful exit of the op pro-
       cess output a non-zero exitcode on stdout then close  that  descriptor.
       For example
            echo "You are denied." 1>&2
            echo 67
            exec 1>&-
       By  directing  the  message to stderr we avoid the API processor, so op
       doesn't prefix the message with the name of the jacket.   Removing  the
       redirection  prefixes the name op was called and the name of the jacket
       to the message.  If you don't want to radiate the name of  the  jacket,
       use stderr.  See op-jacket(7l) for details of the available jackets.

       The expander is very much like the shell's parameter substitution: dol-
       lar sign ($) is the only special character, quotes and backslashes  and
       other  (normally) special characters are only special in the context of
       a dollar expansion.

       Each of the words in the args specified in the selected rule definition
       are  expanded  into at least one word in the argument vector of the new
       process.  The input specification is limited in that there is no way to
       quote white-space from the configuration file parser, but there are two
       ways to get white-space from the expander.

       The command-line specification of the login (its uid) is  available  as
       $u ($U), the specified group (its gid) as $g ($G), the absolute path to
       the file specified as $f, or as an open file descriptor  via  $F.   The
       directory  containing  the file as $d, a read-only open file descriptor
       on that directory is available as $D.

       From the rule definition, the command path as $_, the  mnemonic  speci-
       fied  as  $0,  and  the computed value of $SHELL for MAGIC_SHELL as $S.
       The location of the rule definition allowing the escalation  is  $w  as
       the filename and $W as the line number in that file.  The target direc-
       tory is $x, and if a chroot is specified the target root  directory  is
       $X (otherwise fail the escalation).

       Note  that $S is unique in that it computes what the value of the SHELL
       environment variable  will  be  in  the  escalated  environment,  where
       ${SHELL} is the value from the client environment (if any).

       In  terms of the credentials: the original login name (uid) as $l ($L),
       the escalated login (uid) as $t ($T), the original group as $r ($R) and
       the  escalated  group (gid) as $o ($O).  Read those as "login:real" and
       "to target:other".  The original group (gid) access list  as  $a  ($A),
       the  new  group  (gid)  list as $n ($N).  The initgroups login (uid) is
       available as $i ($I), the PAM session login (uid) as $p ($P).

       The default access configuration as $c and the name  of  the  enclosing
       directory  as  $C.   The home directory of the $l is $h, while the home
       directory of $t is available as $H.  The client's shell  is  $k,  while
       the shell of $t is $K.

       The  original  tty ($y) and umask ($Y) are not usually useful, but when
       you need them they are available.  Two process-ids are  available:  the
       escalated  pid ($z) and the original parent process ($Z).  These ignore
       the usual case relationship because there is no numeric/non-numeric  or
       from/to pair to match together.  These are usually used only in in-line
       scripts, passed as positional parameters.

       The login name op is setuid to is available as as $e, and their uid  as
       $E,  and  that  login's home directory as $~.  The group name under any
       setgid modes is available as $b, the gid as $B.

       Some extra terms are also available: literal dollar ($) as $$, a  space
       as $\s, any other single letter backslash escape tr(1) supports as $\c,
       where c is any of 'a', 'b', 'f', 'n', 'r', 't',  'v',  or  '\'.   Three
       additional  escapes allow access to m4 quotes: 'o' for ' and 'q' for ',
       and the shell double-quote (") as 'd'.  These are for sites where rules
       are  generated  by  m4,  but an expanded value requires quotes.  (Sadly
       this doesn't work for in-line scripts.)

       The expansion of $| is the empty string.  This allows $1 to be  abutted
       to  a  digit  as  $1$|7, which suffixes a seven on the end of the first
       parameter (note that $17 refers to the seventeenth  positional  parame-
       ter).   Pass a single semicolon (;) or ampersand (&) a program by quot-
       ing it with empty expansions as $|;$| or $|&$|.

       The comma separated list of compile-time options are described  by  $^.
       The first option is either "nooptions" (which indicates op doesn't sup-
       port the options expander), or "options".  The last is the  compiled-in
       host  type,  and  the base-100 release number of that platform (used by
       ksb's msrc(8) build chain).  Between these are the  other  compile-time
       options prefixed by "no" if they were disabled.
       This same string is output under -V.

       All  environment variables defined by a rule are expanded (both side of
       the assignment).  As an example:
       Note that the first dollar is the clue to op that this is  an  environ-
       ment  definition,  not  part of the text to be expanded.  In the common
       case expect "HOME_root=/" for the last line.

       An existing environment variable may be substituted with ${env}.   Thus
       we can send the current $PATH value as $old_PATH:

       Lastly  the  complete  identifier for version of op is available as $v,
       and the numeric version as $V.   Also  $q  provides  the  name  op  was
       called,  while  $Q  includes the complete path as given on the command-
       line.  These are largely provided for jacket/helmet support.

       If op includes an affirmative "sentinel" in the options list, then  any
       subdirectory  of the configuration directory which is named for a group
       and owned by that group may contain a configuration that will be active
       when  op  is called by the name of the group.  So a symbolic link to op
       named "staff" forces its configuration from a directory named  "staff",
       if and only if that directory is grouped to staff.

       In  that  case  the group on the directory becomes op's escalated group
       (for $b/$B) and the owner of the directory becomes the escalated  login
       ($e/$E).    The   subdirectory   "OLD"   is  never  consulted,  because
       install(1l) uses it for back-out files.  The directory may also be sym-
       bolic link to a suitable directory.

       Note  that  running  the  sanity check operation (under -S) against the
       default configuration does not check any group-based rule-sets.   Since
       the administrator has out-sourced those rule-sets to the group level op
       never complains to the administrator about them.

       Given the sane policy that every login has their own  group,  sentinels
       allow a rule-sets for each login.  Per-login rule-sets are usually sim-
       pler to do with a single configuration file.   Sentinel  configurations
       are  best  used to allow members of a workgroup or support structure to
       share resources (e.g. chown(2) or chgrp(2) files)  or  start  and  stop

       If  this  support is not compiled into op, a mortal login may compile a
       private copy of the binary to act in a similar  manner.   So,  if  site
       policy  allows setuid/setgid executables, it makes little sense to deny
       requests for the installation sentinel configuration links.   For  com-
       pile  instructions  see  the HTML documentation in the source directory
       for op in the install_base source package.

       Execute op via a symbolic link to op with the name of the target  group
       to access rules for that group.

       op -l
              List  all  the  mnemonic commands available to the current user,
              with some usage information about each.

       op -w
              The output of this command looks like that of  -r  but  includes
              the  reason  each rule is allowed.  For example, "[by group mem-
              bership]" rather than "[by login group name]".  This  tells  you
              why your buddy cannot get to a rule may access.

       op op -w ksb
              Ask  op  to run itself as the superuser to look at ksb's allowed
              mnemonic command list.  This is a clever way to grant members of
              an admin group access to everyone's command list, as well as why
              each login may access each rule.  Here is  a  rule  that  allows
              that access:
              op   /usr/local/bin/op $1 $2 ;

       op -u $LOGNAME chown $PWD/file.pl
              Change  a  file  in  the current directory to the our ownership.
              This might be granted in a common source repository  (for  exam-
              ple) when careless modes stand in the way of progress.  Below is
              a sample rule to allow anyone in group source to  change  owner-
              ship of a file to anyone else in that same group.  Note that the
              the negative RE match forbids using ".." to climb out from under
              chown     /usr/sbin/chown -R $u:source $@ ;
              (The  use  of a recursive option on the chown is site policy, of

       op dmidecode
              Request the human readable version of the DMI table.  Since this
              program has to read the BIOS information it must be run as root,
              since it also gives away more information that you might like it
              can  be  protected  by  op, rather than just setuid to the supe-
              dmidecode /usr/sbin/dmidecode $@ ;
              Similar protections should be afforded to lsof(8).

       op help
              This is a site policy script that usually outputs as much of the
              current  rule-base  as  local  policy  allows.  Some sites don't
              implement it at all, some output the whole rule-set.  Most  just
              output the list of mnemonic commands and some details about what
              each does.

       staff -l
              Request a  list  of  commands  from  the  group  staff  sentinel
              instance.   This  assumes  there  is  a  directory named "staff"
              within (or symbolicly linked from that name to)  the  configura-
              tion  directory,  and that this directory is in group staff (and
              not world or group writable.  The program name allows access  to
              the  rules from that directory and excludes access to the global

       op apache start
              This shows off op's clever use of multiple words to form a human
              friendly  mnemonic.  This rule allows many actions (start, stop,
              restart, and the like) by means of an explicit  RE.   These  may
              then  be  included  in  the  on-line  help under -l.  Note these
              actions are defined as $1 below.
              apache    /usr/local/sbin/apachectl $@ ;
                   uid=root gid=www

              apache    /usr/local/sbin/apachectl $@ ;
                   uid=. gid=.
              Note that  the  second  stanza  doesn't  give  superuser  access
              because  it  is not required: this allows the Customer to always
              put "op" before the common mnemonic.  This really helps sell the
              escalation  to support staff, as that operational policy is easy
              to understand and implement, and may shorten the operators $PATH
              quite  a  bit.   (Multiple  applications might be upgrading to a
              newer version of their webserver, but the path is in the op con-
              figuration,  not in a file they manage. Which allows administra-
              tors and application support to asynchronously update  them,  as
              well as many similar prerequisites.)

              The  additional  rules  that  don't actually escalate privileges
              don't hurt anyone.

       When op is built on a BSD host which  supports  Mandatory  Access  Con-
       trols,  3  additional configuration specification are allowed (they are
       always allowed, just inactive without support):

              The MAC process label of the escalated process will be set  from
              this  text representation.  The label value is expanded with the
              same macro expansion as command.  To additional macros are  sup-
              ported, which are described below.

              The text presented under -m (below) must match one of the speci-
              fied REs.

              The text presented under -m (below) may not  match  any  of  the
              specified REs.

       The  additional macros are $m to access the value specified on the com-
       mand-line under -m, and $M to access the current  process  label.   Any
       use of $m required the specification of -m on the command-line.

       In addition to the above, another command-line option may be allowed to
       specify a new process label for the escalated process.

       -m mac
              Specify (part of) a new MAC label.  The configuration  parameter
              %m  may  limit  the spelling of the requested string, and !m may
              deny some strings.

       To actually set the new process label  the  configuration  element  mac
       should  specify  the  new  label.   The label is expanded with the same
       markup as command.  The typical specification would  be  "mac=$m".   If
       given just that, sanity will complain.  Because the rule should include
       a limit on the spelling of the label (via %m or !m).   A  specification
       of  a fixed label (or one built from other parameters) does not require
       an instance of -m, and less sanity checking.

       If the command below exits success, then the compiled op on  your  host
       supports -m:
              op -H | grep 'mac .* to force -m' >/dev/null

Linux and v1 compatibility
              The  nolog  option just drops the log level from NOTICE to INFO.
              This is because it is never wise to blind the  system  to  audit

       fowners and fperms
              The  fowners  option  should  be  replaced  with %_.owners.  The
              fperms option should  be  replaced  with  %_.perms.   There  are
              aliases  for both of these, which may be specified even if there
              is also a  parallel  %_  specification.  These  aliases  may  be
              removed in the next major version.

              The  xauth  option  should  be  replaced  with  the xdisplay(7l)

              The securid option should be replaced with a local  pam(3)  con-
              figuration, also see pam.conf(5).

              The  help  option  is  not supported, if you want to hide what a
              command does, put it in an in-line script and pass  any  parame-
              ters  in  the environment.  Or even hide the payload in a jacket
              and make the target command do nothing at all (aka.  exit  0  or

       $@ vs $*
              The  use  of  $* and $@ parallels the use of those tokens by the
              shell inside double quotes.  So $* expands to all of  the  posi-
              tional  parameters  as a single word, while $@ expands to 1 word
              for each positional parameter as presented.  There has been some
              confusion about this in older documentation.

       This  version  of  op doesn't honor any quotes (single or double) other
       than the curly brace quote for in-line scripts.   Convert  any  in-line
       scripts,  and replace any other white-space with $\s, $\t, or $\n, then
       remove any quote that are not meant to be literal.

       Some of the in-line scripts Alec suggests may  be  replaced  with  hard
       matches  for $2 to select the correct command.  For example, "op apache
       start" and "op apache stop" could be either a single rule or two  sepa-
       rate rules in this version of op.

       There  is  no support for macros in the configuration file, if you want
       macros use m4 to build your configuration files with msrc or  hxmd(8l).
       The  macros $\d (a shell double quote "), $\o (an m4 open quote '), and
       $\q (an m4 close quote ') are meant to make it  easier  to  markup  the
       configuration file with m4.

       If  you  find  yourself  building lists of login names, try using group
       membership, or netgroups.  When you have common lists of  options,  use
       DEFAULT to refactor them.

       Finally  the  main  configuration  file  is not in the parent directory
       (e.g. /etc/op.conf), rather the name is access.cf in what  ever  direc-
       tory  is compiled in, see -V's output under "access file".  This scheme
       follows the original version more closely.  Building a symbolic link to
       "op/access.cf" from /etc/op.conf doesn't hurt anything, if it makes you

       A comma (,) may be matched literally in a regular  expression  by  dou-
       bling it (,,) to protect it from the separator code.

       Any  failure  to  compile a regular expression is a fatal configuration
       error.  When reported by a Customer these must be fixed by the adminis-

       Older  versions  of  op passed the group access list to the new process
       with little or no deletions in too many cases.   This  has  been  fixed
       since version 2.33.

       The  use  of  substitutions in any regular expression is no longer sup-
       ported.  It was unclear to me that this was ever really useful.

       Older versions of op tried to use \$ to specify a literal dollar  sign,
       but  left  the  backslash in-place.  The double-dollar notation is more
       sane and leaves the over-used backslashes alone.  Also  older  versions
       used  backslash  to escape commas (,) in an RE list, now we use double-
       comma (as an empty RE is never useful to us).

       Any perl  programs  used  as  a  jacket  or  helmet  are  tainted,  see
       perlsec(1).  This is also a feature.

       The  regular expression checker under -S doesn't understand equivalence
       class, so don't use them in the configuration file if you  want  better
       help  text.   It also doesn't really understand ranges (\{n[,m]\}), but
       it may in the future.

       Under -S, the checks for $l, $L, $g, $G, $h, and $H are not limited  in
       every  possible  way; some extra elements are checked that may never be
       allowed for any escalation.  This is also true for most other checks as
       a jacket (helmet) may also deny the escalation based on other criteria,
       so op would never actually execute these combinations.

       Use of the chroot with $D or $F may cause  the  chroot(2)  to  fail  if
       kern.chroot_allow_open_directories is set to 0.

       The  regular  expression match for any explicit users or groups matches
       really should be anchored.  For example, the expression:
       Also  allows  "uprootal"  to  run  the  command.    Since   op   didn't
       traditionally  force  the  anchors  it  still doesn't: but -S complains
       about missing ones.  This might be true for  other  fields,  but  those
       generally don't break as badly as the primary credentials.

       Op  should be able to redirect stdin, stdout, or stderr to a positional
       parameter.  You still need a script or inline-script for that.

       The session feature may be harder when mixed with chroot,  as  the  pam
       configuration might have to be replicated under the new root directory.

       Previous versions of op broke when more than 512 groups were listed  in
       the group file.  This has been fixed since version 2.161, my bad.

       No  security  fixes  have  been applied since before 2008. The last one
       possibly allowed a single extra group to the escalated process.

              The primary access description

              Additional local access descriptions.

              Sentinel configuration for any group.  Always chgrp  the  direc-
              tory and configuration files to group.  Also build a link to the
              op binary named for the group.  The symbolic  link  target  does
              not have to be in (or under) the same directory as op.

              Local escalated scripts.  Other locations are likely, but always
              assure that only authorized changes are possible to scripts  run
              with escalated privileges.

              Local  authorization  jackets and helmets.  These are run as the
              superuser, so the directory should not be updated by  any  other

              Alternate location for the primary description.  For compatibil-
              ity with Alec Thomas's release.

       "Op: A flexible Tool for Restricted Superuser Access", by  "Tom  Chris-
       tiansen",  CONVEX  Computer  Corporation,  "Proceedings  of  the  Large
       Installation Systems Administration III Workshop"

       David Koblas reimplemented op from that description in 1991.

       I consulted the manual page for Alec Thomas's version to improve  Linux

       This  is  a  modification  of  Koblas's  version  by  KS Braunsdorf (at
       ksb.npcguild.org).  KSB added the help and version options  to  conform
       to local (NPC Guild) conventions, and the other whacky options from Jan
       1997 through Feb 2016.  The whole idea of authorization via helmet  and
       jacket  processes was his, as well as most of the command line specifi-
       cations (-u, -g, -f, -m) and on-line help (-H, -a, -l, -r, -w).

       op.cf(5l),  op-jacket(7l),  stamp(7l),  stampctl(8l),  su(1),   csh(1),
       chroot(2),   egrep(1),  getpwuid(3),  pam(3),  getgrgid(3),  sysctl(8),
       innetgr(3), group(5),  passwd(5),  syslog(3),  mac_set_proc(3),  sh(1),
       perl(1), m4(1), setfib(1), msrc(8l), sudo(8), super(8l), echo(1)

                                     LOCAL                               OP(1)