To understand this document

Some use of sudo, op, or other escalation tools, and some shell scripting experience would help a lot.

How to configure op

There are at least 2 configuration files created to represent all the escalation rules available at a site. The first is always named access.cf. This file contains the base-rules and the system-wide defaults, so it changes very little change over time. After we create that one, we'll build other configuration files to represent the current escalation rules.

The number of additional files and their contents will change over time. Rule-set files may be added and deleted as applications shift over time. The rule-sets installed on any host may be different based on local policy.

The name of the file that a given rule comes from is not relevant to your Customer's work-flow. Some configuration error messages include the name of the rule-set and the line number to help the superuser find and repair configuration mistakes, but the Customer should never see this type of error.

Build access.cf

Run op to find out where it expects the configuration directory. I highlighted an example below:
$ op -V
op: $Id: op.m,v 2.digits
op: access file `/etc/op.d/access.cf'
op: using regex
op: multiple configuration files accepted
op: in-line script and $s accepted
op: with pam support, default application "op"
Create that directory path, if it doesn't exist:
$ su
# mkdir -p /etc/op.d
# chmod 0700 # /etc/op.d
Create an empty access file with the proper modes:
# touch /etc/op.d/access.cf
# chmod 0400 /etc/op.d/access.cf

To edit access.cf you should use the really cool program vinst (man page) as the superuser. This edits a copy of the file then uses install to update file and keep a backup copy in an OLD directory. But if you don't want to do that just force-write with your favorite editor.

Once you get a working access file you should move the source to your revision control structure.

Fix sanity errors

The empty configuration is not a valid one, in terms of what op expects. It also expects a PAM configuration, if complied with Pluggable Authentication Module support. So if you run a sanity check on the empty file you should see:
# op -S
op: PAM policy: stat: /etc/pam.d/op: No such file or directory
op: no rules configured, are you sure?

To fix this first configure a PAM policy for op. In this case we'll just link to sudo's policy, if you don't have one of those you can find it with a search engine, or use the su policy in a pinch.

# ls -1 /etc/pam.d | egrep '^(su|sudo|op)$'
su
sudo
# ln -s sudo /etc/pam.d/op
Since PAM configurations are not really standard I can't list the exact one you need here. You do want to include a session line if you want resource limits to work for mortal logins.

Fill in the DEFAULT stanza in the new access policy

I usually start with a DEFAULT stanza that sets the uid to a nonexistent login, such as buddy (that implies you have a site policy against creating a "buddy" account). This prevents and rule without an explicit uid set from ever running, or even passing sanity (under -S).

That would make a file like this:

# $Id: ...
DEFAULT	uid=buddy		# deny rules without a uid set

# no rules yet
Add your own revision control markup where I put $Id: ... so you can keep track of the current revision.

Next replace the comment ("no rules yet") with a harmless rule:

myself	MAGIC_SHELL ;
	users=^.*$
	uid=. gid=. initgroups=.
	$PATH $TERMCAP $TERM $SSH_AUTH_SOCK $SSH_TTY
	$SHELL=/bin/sh $LOGNAME=$l USER=$l $PS1=op$$$\s
This rules allows anyone to escalate to them self. They get a plain shell with a prompt of "op$ ". Try the rule as a mortal. Test the id command and ssh-add -l; they should both work the same as the parent shell.
$ op myself
op$ id
uid=1117(ksb) gid=0(wheel) groups=0(wheel),5(operator),20(staff),810(source)
op$ ssh-add -l
1024 a2:20:5f:14:5f...
op$ exit
$ id
uid=1117(ksb) gid=0(wheel) groups=0(wheel),5(operator),20(staff),810(source)

If that worked then the sanity check should confirm that you have a sane op configuration, with no output.

$ op -S
$

Setup your syslog configuration to capture valuable information

Op logs every escalation attempt. It opens the log stream with LOG_AUTH under the name given as the default PAM module. It logs any configuration error at priority LOG_ERR.

Escalation attempts (failed or succeeded) are logged at priority notice unless the rule is optioned as nolog, which drops the priority to info.

Normally a configuration to send attempts to /var/log/auth.log is enough:

auth.info;authpriv.info			/var/log/auth.log
Check syslog.conf to see where the messages should flow, and make sure that your test escalation is in there. Later you can use a perl script to generate a summary report of all the escalations that took place on each host for management.

Reports based on data from that log help you close the loop on abuse, unused rules, and configuration errors. So write a note now to look into that after you deploy op. My version actually gathers all the logs together to form a picture of the whole site's usage.

The structure of a rule

I always follow a simple structure for each rule: the command template starts on the same line as the mnemonic, followed by 5 groups (with no delimiters between them):
The who parts on a line together.
users, groups, and netgroups
Any parameter limits
$*, $1, $2..., $#, %f, %d, %u, %g, %_,
!*, !1, !2..., !#, !f and the like
Any additional restrictions
pam, password, helment and jacket
The privileges granted
uid, euid, gid, egid, initgroups, chroot, fib and mac
The details of the process environment
$VAR $VAR=value, environment, session, cleanup, dir, stdin, stdout, stderr, basename, daemon, umask and nolog

By following that simple pattern I help auditors understand the rule-base. Every escalation is explained in the same order, so parallel rules are easy to factor into DEFAULT stanzas and grouped into files. This makes the average rule much shorter and easier to explain to someone who only reads the rule-base 4 times a year (or less).

This actually brings up the point that an auditor actually can read the whole rule-base and have a pretty clear understanding of the parts. This is really not the case with sudo, as macros later in the file can have impact on rules above. There is always some doubt as to exactly what any rule (with a macro in it) allows. Since nearly any word in any line may be a macro, that leaves a lot of doubt.

By following a few layout rules one can be sure that op is not grabbing random values from some other place in another file. The only places we can take defaults from are either:

One never has to search unrelated files for other sources.

When it is more clear to order the options in a given rule in a different order then do that: the clarity of the rule is more important than any style preference.

With all that said, we should look at an example (from a real rule-base):

# Allow DBA support to have an easy hook to bring oracle (back) up
oracle  /opt/oracle/oracle_startup ;
	groups=^root$,^oracle$,^dba$,^appdba$
	$1=^startup$
	uid=oracle initgroups=oracle
	$PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
In English I would read that as:
Anyone in either group root, oracle or a dba group can access "oracle startup". This executes a start the oracle_startup script from /opt/oracle, as oracle with all of oracle's groups. This always runs with a fixed PATH set.

What to include in access.cf

I put very few escalation rules in access.cf. However, older versions of op require at least 1 rule in there to keep -S from complaining every time we run sanity. So I have an old "help" rule that was from the time before -l which I include in that file (since my Customers still use it). I also put any local rules for operators or admins that should be on every host at the site.

Here is the old help rule. While not as pretty as I'd like it, it does get the job done.

help	{	cd $0 || exit 65
		echo "op mnemonic    UNIX command"
		echo "===========    ============"
		sed -n -e "s/#.*//" \
			-e "/^DEFAULT/d" \
			-e "s/^\\([^ 	][^ 	]*\\)[ 	][ 	]*\\(.*\\)[&].*/\\1#\\2/p" \
			-e "/^\\([^ 	][^ 	]*\\)[ 	][ 	]*{.*/{" \
				-e "s//\\1#{script}/" \
				-e "h" \
				-e ": loop" \
				-e "N" \
				-e "s/.*\\n[ 	]*//" \
				-e "/^[^}]/b loop" \
				-e H \
				-e x \
				-e "s/\\n}[ 	]*\\(.*\)[;&]/ \\1/p" \
			-e "}" *.cf |
		sort |
		pr -t -e"#15"
	} $C ;
	users=^.*$
	uid=root
replace the "myself" rule with something like "help" or some other rule you need every place. Update the access file until it has the basic rules you need for operations, but nothing for applications. Make sure at each step that sanity (op -S) outputs only message you'll accept by policy.

Build other files with names for the purpose

If you have a project that runs a few services you can make a rule-base for the project that has an obvious name (like the name of the project with a ".cf" on the end). If you have a local way to distribute only the rule-base files that are actually needed on each host, then you can rest assured that the "idle" rules can't be accessed to do anything unexpected.

Allow access to the rules by group membership and allow a few escalations for different project-related groups. That way you have a `least privilege' structure and a way to enforce it. If you don't have a good login accounting structure, make one so changing group membership is easy.

Production support
Allow start, stop, check config and maybe a trace on/off rule.
Developers
Allow a rule to get a stack trace or core dump of the running service. Allow a rule to toggle a trace flag. Never allow any data copy rules here, we don't want people to copy Customer data back to the test lab.
Operators
System support staff might need to truncate a log file, run backups as root, kill processes (via pkill), or chown files under /tmp or /var/tmp. I never give operators a root shell via op, they have physical access to the console and a way to get a superuser shell from there.
Admins
Allow a rule to build ant required empty directories for application installs. Maybe run rsync from a trusted repository into the target /opt/ directory to prime any new system for the initial load of the package, or add the RPM for the package without a general root shell. Allow them to truncate or roll log files that may fill disks.

You might include them in any of the previous rule lists, since they can just su to do it anyway, and we'd rather log the access.

Now it is just a matter of converting or making rules to allow exactly what you need. No more "sudo /bin/bash" to do everything with the black pointy hat with stars, shells, and cats on it. No more late calls to turn trace on for a developer. No more painful audit misunderstandings.

Keep these files under revision control so you can show the auditor the differences from the last audit first. Then have them look over the whole rule-base. This actually speeds any audit, a lot.

Meta markup

I actually marked-up my rules with m4 to customize the policy for each target host's OS type and version, the "class" of server, the "level" of test, and the list of "services" it should be running. This allows some additional rules to developers at the lower levels of test (stop/start) that they are not allowed in production. This also allows the whole-sale deletion of test rules in production.

Do this by adding-to or changing the name of the group that allows access the extra rules. The that makes the revision tag on the file the same, but the content slightly different when installed. (In fact no hosts gets the m4 markup installed because op doesn't know how to read the marked-up file.)

For example this m4 quotes all the rule, except the PRIVGROUP macro, which is driven to be either the empty string (in production) or a list of REs that match the puma developers login groups (in development).

`# $Id: ..
puma-web        /opt/syzygy/puma/ctl puma-web $* ;
		groups=^ppm$,^root$,^pumadev$,^cfgmgt$'PRIVGROUP`
		uid=puma
'dnl

There is a really handy set of tools to install marked-up files across many hosts called msrc, hxmd and xapply. These are very much like GNU parallel, but they are specialized to running files through m4 for each target host. That makes them perfect for integrations with my version of op which doesn't use the default m4 quotes (` and ') for anything.

Op's expander has 2 markups to allow the insertion of the default m4 quotes into variables: $\o for an open quote (`) and $\q for a close quote ('). I've never needed them in an real rule-base. If you want m4 quotes in an in-line script you'll have to chanequote in the source file. Always restore the default quotes before the end of the file, for the case where that file is include'd by another.

Special markup for options and defaults

Op allows access to at least 3 command-line options. There are forced into the usage message for any mnemonic rule that uses them.

Specify a group under -g

A group might be used to specify the new group ownership of a file, or the target group for an escalation. The group may be limited by name or gid, see the limits in the main page.

Any rule that uses the markup $g or %g will require a -g option on the command-line.

Specify a login under -u

A login might be used to specify the new owner of a file, or the target login for an escalation, or the home directory of that login may be requested. The login may be limited by name or uid, see the limits in the main page.

Any rule that uses the markup $u or %u will require a -u option on the command-line.

Here is an example rule which uses -u to allow any member of group "source" to chown a subdirectory of 3 different hierarchies to any login who is also in group source.

level2s-chown	/usr/sbin/chown -R $u:source $* ;
		groups=^source$
		uid=root
		%u@g=^source$
		$*=^/tmp/.*-[0-9],^/usr/msrc/,^/usr/src/
		!*=/\.\./

The list commands option displays that escalation as:

op -u uid level2s-chown [args]

Specify a file under -f

The -f option forces a filename (or directory name) into the op command. That file may be limited to a known directory, a particular mode or type, or even by the exact file size or timestamp, see the list in the main page.

A file might be used to start a trace log, or specify a directory to create, update, or remove. There is no set purpose for the option because it is intended to be purposed by the rule's intent.

Any rule that uses the markup $f, %f, $d or %d will require a -f option on the command-line.

Here is an example rule which uses -u and -f:

java-generated  $f $* ;
		users=^monitor$,^root$
		uid=%u egid=%u gid=%u initgroups=%u
		%u@g=^wlsapp$
		%f.path=^/var/syzygy/bjoss/generated/[^/]+/[^/]+/[^/]+$
		%f.type=^-..x
		$PATH $LD_LIBRARY_PATH

The help options lists that rule as:

op -u uid -f file java-generated [args]

Specify part of a MAC label under -m

If your host supports Mandatory Access Control process labels (like FreeBSD 6 and above), then op can set a process label on the escalated process. And a command-line option can be part of that label.

The mac configuration option is different than all the other options: it's right-hand-side is expanded like an environment variable. All the dollar-sign markup (most notably $m and $M) are available to form the new process label. Limits my be placed on the -m option's specification via %m (must match) and !m (must never match) limits.

Some keywords allow special markup

In the context of some keywords op allows a run-time value to be substituted in place of a single percent markup. These markups cannot be part of a longer string, and cannot be sliced or diced when substituted, but they are polymorphic in that they provide a context specific form of the requested data.

These "percent markups" are bound to bits of the command line or the attributes of the parent process that op inherited. They may be specified in place of a literal string under some keywords to substitute run-time values where a fixed string would normally be required.

%f
Bound to the file given under -f file. This path is always made into an absolute path. The macro to expand the path as a command parameter is $f, or $F as an fd. Many limits may be placed on the file with keywords that start with "!f" or "%f".
%d
Bound to the dirname of the file specified under -f. Available as $d in the expander. Also available as an fd with $D, if you need to fchdir(2) to it later.
%u
Bound to the login specified under -u. Limited by the keywords %u and !u. Available as the $u macro, or by uid as $U.
%g
Bound to the group specified under -g. Limited by the keywords %g and !g. Available as the $g macro, or by gid as $G.
%l
The login name we found for the Customer running op. Limited by users, groups, and netgroups. Available as the $l macro, or by uid as $L.
%i
The best guess the op can make as to which login the initgroups keyword should default to, or the value specified to initgroups. Usually any uid, euid. Available via the $i and $I macros.

The meaning of various precent tokens in the context of each keyword

Remember that the file is reformatted into an absolute path for the escalated process. This is usually safer than a relative path, but can be problematic under a chroot, use $X to pass the new root down so the escalated process can remove it, or use $F to pass an open file descriptor on to the escalated process.
rule	/usr/local/libexec/op/myScript -r $X $f ;
	%f.path=^/usr/host/lv426/home/local/[^/.]+$
	%f.perms=^dr.x
	chroot=/usr/host/lv426
	...

In the table below the dir (expanded from %d) is the string that would be output by applying dirname to the absolute path produced for file. In the example above it should always be "/usr/host/lv426/home/local".

The term login refers to the login name specified by uid, if that were numeric then match returned by getpwuid(3).

keywordempty%f%d%u%g%l or .default
dir/filedirlogin's
home dir
login's
home dir
none,
under chroot /
chrootnonefiledirlogin's
home dir
perp's
home dir
none
egid%lfile's giddir's gidlogin's
primary group
groupreal gidop's effective
gid
gid list%lfile's giddir's gidlogin's
primary group
grouporiginal listegid
uid%lfile's uiddir's uidlogin's
primary group
perpop's effective uid
euid%lfile's uiddir's uidlogin's
primary group
perpuid
initgroupsuid's
groups
file's owner's
groups
dir's owner's
groups
loginoriginal listuid's groups
sessionnonefile's ownerdir's ownerloginperpnone
cleanupnonefile's ownerdir's ownerloginperpnone
password listnonefile's owner's
password
dir's owner's
password
login's passwordperp's
password
none
pamnone. sets
-V default
none
stdout stdin
stderr
/dev/nullfileoriginal I/O
(†) In the context of session and cleanup the markup
%i requests the same specification as initgroups.

In general is it poor form to use a percent keyword for two purposes in a single escalation rule. For example using %f as both a chroot and a chdir might not be what you meant (since the directory path is already relative to the new root). Op's sanity checker takes some care to complain about semantically questionable combinations of usages.

There is no way to markup an escalation rule to tell op that it is semantically sane: if it complains about something you think is always OK, submit a bug report.

Conversion from Alec Thomas's version to version ksb's

If you've been using the Linux op package you may have used some of Alec's extensions. If so here are some ideas for converting to my branch.

Target binary checks

The fowners and fusers keywords should be replaced with %_.owners and %_.users. There are a lot more things to check under %_ and !_. By using any of the attr specifications.
# a test rule only
any	$1 ;
	%_.perms=^-r.xr-xr-x
	%_.path=^/bin/ls$
	!_.login=^nobody$

Other options

The nolog specification still calls syslog, but with the level set to INFO rather than NOTICE. So you can tune /etc/syslog.conf to drop the nolog into a different file, or the bit-bucket.

The securid should be replaced with a local pam policy.

The xauth specification should be mapped to jacket=xdisplay. The xdisplay jacket is available in the "op-jackets" package.

Macros (or variables)

Alec added a macro feature (var=value). I don't name individual accounts often in rules, because it has been my experience with both op and sudo that list of logins named in the rule-base get stale quickly. So I don't list people by login name the rule-base. I actually use group membership in almost every case and where I don't I use netgroups, both of which I manage with a better accounting structure.

For host specific changes I use m4 to markup rules, then process the marked-up file before I install it on every host. I've coded a whole stack of tools to make this easy, so I don't need a macro processor inside every program that reads a configuration file. See msrc(8) for a brief description, and the HTML documents in for that program and hxmd(8).

For audit purposes it is much better to have all the context of an escalation rule visible on a terminal window. Using variables makes that very hard. Using DEFAULT stanzas from another file is also poor form.

Quotes

Alec added quoted strings to the configuration file syntax, my version sticks with the traditional version that says quotes are not special characters. This makes sense in light of my use of m4 to pre-process files.

Alec uses forms like:

# Switch inetd on and off, shows complex
# shell example and 'string' arguments. $1
# in this example is expanded by op
inetd /bin/sh -c '
		case $1 in
		on) /usr/sbin/inetd -s ;;
		off) /usr/bin/pkill inetd ;;
		esac
	' ;
	users=ACCESS_LIST
	$1=on|off

To make it look as much like the original as we can use an in-line script. In version 2 this is quoted with a curly brace markup:

# Switch inetd on or off using an in-line script
inetd	{	case "$1" in
		on) /usr/sbin/inetd -s ;;
		off) /usr/bin/pkill inetd ;;
		esac
	} $1 ;
	groups=^wheel$ uid=0
	$1=^on$,^off$
Which outputs the usage line:
op inetd on|off
This assumes that the same group of people are able to turn inetd off and on. In this version of op, since matching the positional parameters also selects the rule, we could also code that as:
# Switch inetd on or off, using separate rules
inetd	/usr/sbin/inetd -s ;
	$1=^on$
	groups=^operator$,^wheel$ uid=0

inetd	/usr/bin/pkill -U root inetd ;
	$1=^off$
	groups=^wheel$ uid=0
Which outputs 2 usage lines:
op inetd on
op inetd off
And also has the feature that more people might be able to start inetd than can stop it.

An important difference is the explicit uid=0 specification, which keeps the -S sanity checker from complaining about the target uid defaulting to the superuser.

Other uses for quotes

Alec's version has a help specification which masks the -l output for a rule with some fixed text. The version doesn't have that. The list output is supposed to show the command-line usage for each rule, hiding it would make it very hard to access a rule. Rather we try to add some semantic clues to the output based in some guess as to the purpose of common REs.

Op guesses that a string that matches all digits is a "number". If that matches 3 dots and the rest digits we think it is an "IP", if it has a slash and more digits on the end it is a "CIDR". If the strings is anchored left and right and has no character ranges we list the string as-is (viz. $1=^start$ lists "start"). Disjunctions list all the alternatives (with either "|" or "," notation).

The other use of quotes would be to quote white-space. Unless you were to need an RE that must match white-space you never need spaces in my version, and you can use [:space:] to match a space.

In the expansion of a parameter you must encode spaces as $\s, which is long, but I've almost never needed to do it.

Quotes are never needed to escape a double or single quote, backslash, comma, or dollar sign. To quote a dollar sign use $$, you don't need to quote " or '. To quote a comma in an RE use ,,. This is safe because an empty RE is never useful to op. To quote a literal semicolon (ampersand) in a command use a set of empty expansions around them: $|;$| ($|&$|).

Internal expanders

There are some internal expanders that are used to make $_ possible:
$.
This forces a break in the expansion, shifting to the next shell word. This is a rather unobvious way to echo "hello world":
hi	echo$.hello$.world ;
	...
	$NAME=KS$.Braunsdorf
In the context of an environment variable the word break becomes a space character. So the NAME environment variable is assigned "KS Braunsdorf".

These expansion are used (with a bit of hand waving) to build $_ (the name of the escalated program) before op expands the full specification. I'm not sure if they are useful in many other contexts.

How to express some sudo options under op

I've never been a big fan of sudo because (as far as I can tell) it is largely geared for sysadmins to do tasks mostly as root. My customers need to start and stop applications as a pseudo-login (not as the superuser).

My customers want a mnemonic that is easy to type and does the right thing. My customers don't want to ever type options like -u. They also require that I have an audit of the rule-base (for SOX 404 compliance).

I tried to make this branch of op meet those requirements. But I realize that some people like the options sudo supports, so here are some clues to help you convert some of your rules to my way of thinking.

always_set_home
secure_path
Set the environment variable in a DEFALUT stanza (or on a given escalation rule):
DEFAULT	$HOME=$h
	$PATH=the path you think is secure
env_reset
setenv
This is the default. There are two ways to pass a client environment variable as-is: either match it under environment, or name it as an option without a value.
rule	... ;
	environment=^HOME$,^NAME$,^ORGANIZATION$
	$TERM $TERMCAP

To pass all of the customer's environment specify environment without a value.

authenticate
Use a pam specification to tune any authentication rules, that is what pam is all about.
closefrom_override
A helmet or jacket may force a command to close all file descriptors above a specific value, for example to close all above 3: &3. In addition it may specify a redirection of stdin, stdout, or stderr (for example &0=/etc/motd). These commands are output to the stdout of the helmet process before it releases the escalated process.
env_editor
editor
There is no support in op to escalate an editor session, use vinst -U to do that.
fqdn
There is no support in op to parse hostnames in the access list. Use netgroups to escalate based on a host name, or markup your rule-base with m4 and pre-process it before you install the rule-set.
ignore_dot
Set path explicitly, or filter it with a helmet.
ignore_local_sudoers
There is no support in op to distill a rule-base from LDAP. Build a program to update the local rule-base at intervals from any source you like.
insults
Code a helmet, or add a pam module to insult your Customers, if you feel a pressing need to do so.
log_host
log_year
loglinelen
syslog_badpri
syslog_goodpri
logfile
syslog
The syslog format of an escalation doesn't change, because they are almost always machine parsed for audit purposes. We always use syslog to log escalations for the same reason, and always at the same levels.
long_otp_prompt
passprompt_override
pwfeedback
passwd_tries
passwd_timeout
passprompt
askpass
Set in the pam stack, or modify a module and push the change back up-stream.
mail_always
mail_badpass
mail_no_host
mail_no_perms
mail_no_user
badpass_message
mailsub
mailerflags
mailerpath
mailfrom
mailto
We do not mail notifications. Monitor the log files with your log monitoring tool (that you have to have anyway).
noexec
Setup a noexec context with a wrapper program, or an LD_PRELOAD set in the rules that need it.
path_info
Since op only lists the mnemonic for the failed escalation there is no radiation of path information.
preserve_groups
Use initgroups=login to set the groups by login, or gid=group1,group2... to set an explicit list. By default the groups in the escalated process are those of the target uid (or euid).
requiretty
A helmet to do with is as simple as:
#!/bin/sh
test -t 2 && exit 0
echo "Must be run from a tty"
echo 77				# EX_NOPERM
Note that this checks stderr rather than stdin since the input to the jacket is always the null device.
root_sudo
If you don't want the superuser to run any given rule, don't allow it.
rootpw
runaspw
Set password=whomever for the rule.
set_home
set_logname
Set any environment you want
$HOME=$H
$LOGNAME=$l $USER=$l
shell_noargs
There is not a default mnemonic under op. If "op su" is too long to type, then build a script named "h", since that key is in the home row. (Yes, I'm being sarcastic.)
fast_glob
Op doesn't glob. See my glob shell tool to process shell meta patterns.
stay_setuid
Set any combination of uid, euid, gid, and/or egid you need, per rule.
targetpw
Set password=%u to ask for -u's password, or Set password=%f to ask for the owner of -f's file's password. Really ask for any credentials you really want with pam.
tty_tickets
timestamp_timeout
timestampdir
timestampowner
verifypw
If you want stamp based authorization, there is a helmet for that. Search the jacket HTML page for stampctl and stamp usage. This is way more powerful than a simple timestamp.
umask_override
Set umask=octal. There is no relative umask feature in op.
visiblepw
If this is a good idea, we should push it back into pam's password interaction.
closefrom
The helmet to do this is:
#!/bin/sh
echo "&3"
Where "3" is the lowest file descriptor to close.
umask
Set any umask you want with the umask option. There is not a function to create a variable umask in op.
noexec_file
Set the pre-load with the environment variable.
runas_default
If a rule requires a -u then one must be presented. Allow the distinct version with a different mnemonic.
sudoers_locale
Op doesn't use any locale conversions when parsing the configuration file.
env_file
Use a helmet that outputs the required environment:
#!/bin/sh
echo '$MY_VAR1=this value with spaces in it'
echo "\$MY_VAR2=$PATH"
echo 0
exempt_group
Escalations without a password or pam option do not ask for any authentication.
lecture
lecture_file
Feel free to build a jacket that does this, if you need it.
listpw
All users can list their own rules, to enable others write an op rule to allow others to see parts of the rule-base.
env_check
env_delete
env_keep
A helmet that filters the environment is quite possible, put such rules in there. Here is a prototype for the check function:
#!/bin/sh
# Remove variables with percent or slash in them from the list in $env_check
for name in `echo $env_check | tr ',' ' '`; do
	if eval expr _\"\${$name}\" : _\'.\*\[/%\].\*\' >/dev/null ; then
		echo "-$name"
	fi
done
echo "-env_check"
echo 0
Hook it into a rule with
rule	$NAME $PATH ...
	$env_check=NAME,PATH,...
	jacket=/usr/local/libexec/jacket/env_check

Return

Go back to the main page, or back to refs.
$Id: config.html,v 2.21 2012/10/06 19:39:56 ksb Exp $