516 lines
17 KiB
Plaintext
516 lines
17 KiB
Plaintext
=cut
|
|
Copyright (c) 1994-1996,1998-1999 Todd C. Miller <Todd.Miller@courtesan.com>
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions
|
|
are met:
|
|
|
|
1. Redistributions of source code must retain the above copyright
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
2. Redistributions in binary form must reproduce the above copyright
|
|
notice, this list of conditions and the following disclaimer in the
|
|
documentation and/or other materials provided with the distribution.
|
|
|
|
3. The name of the author may not be used to endorse or promote products
|
|
derived from this software without specific prior written permission
|
|
from the author.
|
|
|
|
4. Products derived from this software may not be called "Sudo" nor
|
|
may "Sudo" appear in their names without specific prior written
|
|
permission from the author.
|
|
|
|
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
$Sudo$
|
|
=pod
|
|
|
|
=head1 NAME
|
|
|
|
sudoers - list of which users may execute what
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
The I<sudoers> file is composed two types of entries:
|
|
aliases (basically variables) and user specifications
|
|
(which specify who may run what). The grammar of I<sudoers>
|
|
will be described below in Extended Backus-Naur Form (EBNF).
|
|
Don't despair if you don't know what EBNF is, it is fairly
|
|
simple and the definitions below are annotated.
|
|
|
|
=head2 Quick guide to EBNF
|
|
|
|
EBNF is a concise and exact way of describing the grammar of a language.
|
|
Each EBNF definition is made up of I<production rules>. Eg.
|
|
|
|
symbol ::= definition | alternate1 | alternate2 ...
|
|
|
|
Each I<production rule> references others and thus makes up a
|
|
grammar for the language. EBNF also contains the following
|
|
operators, which many readers will recognize from regular
|
|
expressions. Do not, however, confuse them with "wildcard"
|
|
characters, which have different meanings.
|
|
|
|
=over 8
|
|
|
|
=item C<?>
|
|
|
|
Means that the preceding symbol (or group of symbols) is optional.
|
|
That is, it may appear once or not at all.
|
|
|
|
=item C<*>
|
|
|
|
Means that the preceding symbol (or group of symbols) may appear
|
|
zero or more times.
|
|
|
|
=item C<+>
|
|
|
|
Means that the preceding symbol (or group of symbols) may appear
|
|
one or more times.
|
|
|
|
=back
|
|
|
|
Parentheses may be used to group symbols together. For clarity,
|
|
we will use single quotes ('') to designate what is a verbatim character
|
|
string (as opposed to a symbol name).
|
|
|
|
=head2 Aliases
|
|
|
|
There are four kinds of aliases: the C<User_Alias>, C<Runas_Alias>,
|
|
C<Host_Alias> and C<Cmnd_Alias>.
|
|
|
|
Alias ::= User_Alias = User_Alias (':' User_Alias)* |
|
|
Runas_Alias (':' Runas_Alias)* |
|
|
Host_Alias (':' Host_Alias)* |
|
|
Cmnd_Alias (':' Cmnd_Alias)*
|
|
|
|
User_Alias ::= NAME '=' User_List
|
|
|
|
Runas_Alias ::= NAME '=' Runas_User_List
|
|
|
|
Host_Alias ::= NAME '=' Host_List
|
|
|
|
Cmnd_Alias ::= NAME '=' Cmnd_List
|
|
|
|
NAME ::= [A-Z]([A-Z][0-9]_)*
|
|
|
|
Each I<alias> definition is of the form
|
|
|
|
Alias_Type NAME = item1, item2, ...
|
|
|
|
where I<Alias_Type> is one of C<User_Alias>, C<Runas_Alias>, C<Host_Alias>,
|
|
or C<Cmnd_Alias>. A C<NAME> is a string of upper case letters, numbers,
|
|
and the underscore characters ('_'). A C<NAME> B<must> start with an
|
|
upper case letter. It is possible to put several alias definitions
|
|
of the same type on a single line, joined by a semicolon (':'). Eg.
|
|
|
|
Alias_Type NAME = item1, item2, item3 : NAME = item4, item5
|
|
|
|
The definitions of what constitutes a valid I<alias> member follow.
|
|
|
|
User_List ::= User |
|
|
User ',' User_List
|
|
|
|
User ::= '!'* username |
|
|
'!'* '#'uid |
|
|
'!'* '%'group |
|
|
'!'* '+'netgroup |
|
|
'!'* User_Alias
|
|
|
|
A C<User_List> is made up of one or more usernames, uids
|
|
(prefixed with '#'), System groups (prefixed with '%'),
|
|
netgroups (prefixed with '+') and other aliases. Each list
|
|
item may be prefixed with one or more '!' operators. An odd number
|
|
of '!' operators negates the value of the item; an even number
|
|
just cancel each other out.
|
|
|
|
Runas_List ::= Runas_User |
|
|
Runas_User ',' Runas_List
|
|
|
|
Runas_User ::= '!'* username |
|
|
'!'* '#'uid |
|
|
'!'* '%'group |
|
|
'!'* +netgroup |
|
|
'!'* Runas_Alias
|
|
|
|
Likewise, a C<Runas_List> has the same possible elements
|
|
as a C<User_List>, except that it can include a C<Runas_Alias>,
|
|
instead of a C<User_Alias>.
|
|
|
|
Host_List ::= Host |
|
|
Host ',' Host_List
|
|
|
|
Host ::= '!'* hostname |
|
|
'!'* ip_addr |
|
|
'!'* network(/netmask)? |
|
|
'!'* '+'netgroup |
|
|
'!'* Host_Alias
|
|
|
|
A C<Host_List> is made up of one or more hostnames, IP addresses,
|
|
network numbers, netgroups (prefixed with '+') and other aliases.
|
|
Again, the value of an item may be negated with the '!' operator.
|
|
If you do not specify a netmask with a network number, the netmask
|
|
of the host's ethernet interface(s) will be used when matching.
|
|
The netmask may be specified either in dotted quad notation (eg.
|
|
255.255.255.0) or CIDR notation (number of bits, eg. 24).
|
|
|
|
Cmnd_List ::= Cmnd |
|
|
Cmnd ',' Cmnd_List
|
|
|
|
commandname ::= filename |
|
|
filename args |
|
|
filename '""'
|
|
|
|
Cmnd ::= '!'* commandname |
|
|
'!'* directory |
|
|
'!'* Cmnd_Alias
|
|
|
|
A C<Cmnd_List> is a list of one or more commandnames, directories, and other
|
|
aliases. A commandname is a fully-qualified filename which may include
|
|
shell-style wildcards (see `Wildcards' section below). A simple
|
|
filename allows the user to run the command with any arguments he/she
|
|
wishes. However, you may also command line arguments (including wildcards).
|
|
Alternately, you can specify C<""> to indicate that the command
|
|
may only be run B<without> command line arguments. A directory is a
|
|
fully qualified pathname ending in a '/'. When you specify a directory
|
|
in a C<Cmnd_List>, the user will be able to run any file within that directory
|
|
(but not in any subdirectories therein).
|
|
|
|
If a C<Cmnd> has associated command line arguments, then the arguments
|
|
in the C<Cmnd> must match exactly those given by the user on the command line
|
|
(or match the wildcards if there are any). Note that the following
|
|
characters must be escaped with a '\' if they are used in command
|
|
arguments: ',', ':', '=', '\\'.
|
|
|
|
=head2 User Specification
|
|
|
|
Runas_Spec ::= '(' Runas_List ')'
|
|
|
|
Cmnd_Spec ::= Runas_Spec? ('NOPASSWD:' | 'PASSWD:')? Cmnd
|
|
|
|
Cmnd_Spec_List ::= Cmnd_Spec |
|
|
Cmnd_Spec ',' Cmnd_Spec_List
|
|
|
|
User_Spec ::= User_list Cmnd_Spec_List (':' User_Spec)*
|
|
|
|
A B<user specification> determines which commands a user may run
|
|
(and as what user) on specified hosts. By default, commands are
|
|
run as B<root> but this can be changed on a per-command basis.
|
|
|
|
Let's break that down into its constituent parts:
|
|
|
|
=head2 Runas_Spec
|
|
|
|
A C<Runas_Spec> is simply a C<Runas_List> (as defined above)
|
|
enclosed in a set of parentheses. If you do not specify a
|
|
C<Runas_Spec> in the user specification, a default C<Runas_Spec>
|
|
of B<root> will be used. A C<Runas_Spec> sets the default for
|
|
commands that follow it. What this means is that for the entry:
|
|
|
|
dgb boulder = (operator) /bin/ls, /bin/kill, /usr/bin/who
|
|
|
|
The user B<dgb> may run F</bin/ls>, F</bin/kill>, and
|
|
F</usr/bin/lprm> -- but only as B<operator>. Eg.
|
|
|
|
sudo -u operator /bin/ls.
|
|
|
|
It is also possible to override a C<Runas_Spec> later on in an
|
|
entry. If we modify the entry like so:
|
|
|
|
dgb boulder = (operator) /bin/ls, (root) /bin/kill, /usr/bin/lprm
|
|
|
|
Then user B<dgb> is now allowed to run F</bin/ls> as B<operator>,
|
|
but F</bin/kill> and F</usr/bin/lprm> as B<root>.
|
|
|
|
=head2 NOPASSWD and PASSWD
|
|
|
|
By default, B<sudo> requires that a user authenticate him or herself
|
|
before running a command. This behavior can be modified via the
|
|
C<NOPASSWD> tag. Like a C<Runas_Spec>, the C<NOPASSWD> tag sets
|
|
a default for the commands that follow it in the C<Cmnd_Spec_List>.
|
|
Conversely, the C<PASSWD> tag can be used to reverse things.
|
|
For example:
|
|
|
|
ray rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm
|
|
|
|
would allow the user B<ray> to run F</bin/kill>, F</bin/ls>, and
|
|
F</usr/bin/lprm> as root on the machine rushmore as B<root> without
|
|
authenticating himself. If we only want B<ray> to be able to
|
|
run F</bin/kill> without a password the entry would be:
|
|
|
|
ray rushmore = NOPASSWD: /bin/kill, PASSWD: /bin/ls, /usr/bin/lprm
|
|
|
|
=head2 Wildcards (aka meta characters):
|
|
|
|
B<sudo> allows shell-style I<wildcards> to be used in pathnames
|
|
as well as command line arguments in the I<sudoers> file. Wildcard
|
|
matching is done via the B<POSIX> C<fnmatch(3)> routine. Note that
|
|
these are I<not> regular expressions.
|
|
|
|
=over 8
|
|
|
|
=item C<*>
|
|
|
|
Matches any set of zero or more characters.
|
|
|
|
=item C<?>
|
|
|
|
Matches any single character.
|
|
|
|
=item C<[...]>
|
|
|
|
Matches any character in the specified range.
|
|
|
|
=item C<[!...]>
|
|
|
|
Matches any character B<not> in the specified range.
|
|
|
|
=item C<\x>
|
|
|
|
For any character "x", evaluates to "x". This is used to
|
|
escape special characters such as: "*", "?", "[", and "}".
|
|
|
|
=back
|
|
|
|
Note that a forward slash ('/') will B<not> be matched by
|
|
wildcards used in the pathname. When matching the command
|
|
line arguments, however, as slash B<does> get matched by
|
|
wildcards. This is to make a path like:
|
|
|
|
/usr/bin/*
|
|
|
|
match C</usr/bin/who> but not C</usr/bin/X11/xterm>.
|
|
|
|
=head2 Exceptions to wildcard rules:
|
|
|
|
The following exceptions apply to the above rules:
|
|
|
|
=over 8
|
|
|
|
=item C<"">
|
|
|
|
If the empty string C<""> is the only command line argument in the
|
|
I<sudoers> entry it means that command is not allowed to be run
|
|
with B<any> arguments.
|
|
|
|
=back
|
|
|
|
=head2 Other special characters and reserved words:
|
|
|
|
The pound sign ('#') is used to indicate a comment (unless it
|
|
occurs in the context of a user name and is followed by one or
|
|
more digits, in which case it is treated as a uid). Both the
|
|
comment character and any text after it, up to the end of the line,
|
|
are ignored.
|
|
|
|
The reserved word B<ALL> is a a built in I<alias> that always causes
|
|
a match to succeed. It can be used wherever one might otherwise
|
|
use a C<Cmnd_Alias>, C<User_Alias>, C<Runas_Alias>, or C<Host_Alias>.
|
|
You should not try to define your own I<alias> called B<ALL> as the
|
|
built in alias will be used in preference to your own.
|
|
|
|
An exclamation point ('!') can be used as a logical I<not> operator
|
|
both in an I<alias> and in front of a C<Cmnd>. This allows one to
|
|
exclude certain values. Note, however, that using a C<!> in
|
|
conjunction with the built in C<ALL> alias to allow a user to
|
|
run "all but a few" commands rarely works as intended (see SECURITY
|
|
NOTES below).
|
|
|
|
Long lines can be continued with a backslash ('\\') as the last
|
|
character on the line.
|
|
|
|
Whitespace between elements in a list as well as specicial syntactic
|
|
characters in a I<User Specification> ('=', ':', '(', ')') is optional.
|
|
|
|
=head1 EXAMPLES
|
|
|
|
Below are example I<sudoers> entries. Admittedly, some of
|
|
these are a bit contrived. First, we define our I<aliases>:
|
|
|
|
# User alias specification
|
|
User_Alias FULLTIMERS = millert, mikef, dowdy
|
|
User_Alias PARTTIMERS = bostley, jwfox, crawl
|
|
User_Alias WEBMASTERS = will, wendy, wim
|
|
|
|
# Runas alias specification
|
|
Runas_Alias OP = root, operator
|
|
Runas_Alias DB = oracle, sybase
|
|
|
|
# Host alias specification
|
|
Host_Alias SPARC = bigtime, eclipse, moet, anchor :\
|
|
SGI = grolsch, dandelion, black :\
|
|
ALPHA = widget, thalamus, foobar :\
|
|
HPPA = boa, nag, python
|
|
Host_Alias CUNETS = 128.138.0.0/255.255.0.0
|
|
Host_Alias CSNETS = 128.138.243.0, 128.138.204.0/24, 128.138.242.0
|
|
Host_Alias SERVERS = master, mail, www, ns
|
|
Host_Alias CDROM = orion, perseus, hercules
|
|
|
|
# Cmnd alias specification
|
|
Cmnd_Alias DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\
|
|
/usr/sbin/restore, /usr/sbin/rrestore
|
|
Cmnd_Alias KILL = /usr/bin/kill
|
|
Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm
|
|
Cmnd_Alias SHUTDOWN = /usr/sbin/shutdown
|
|
Cmnd_Alias HALT = /usr/sbin/halt, /usr/sbin/fasthalt
|
|
Cmnd_Alias REBOOT = /usr/sbin/reboot, /usr/sbin/fastboot
|
|
Cmnd_Alias SHELLS = /usr/bin/sh, /usr/bin/csh, /usr/bin/ksh, \
|
|
/usr/local/bin/tcsh, /usr/bin/rsh, \
|
|
/usr/local/bin/zsh
|
|
Cmnd_Alias SU = /usr/bin/su
|
|
|
|
The I<User specification> is the part that actually determines who may
|
|
run what.
|
|
|
|
root ALL = (ALL) ALL
|
|
%wheel ALL = (ALL) ALL
|
|
|
|
We let B<root> and any user in group B<wheel> run any command on any
|
|
host as any user.
|
|
|
|
FULLTIMERS ALL = NOPASSWD: ALL
|
|
|
|
Full time sysadmins (B<millert>, B<mikef>, and B<dowdy>) may run any
|
|
command on any host without authenticating themselves.
|
|
|
|
PARTTIMERS ALL = ALL
|
|
|
|
Part time sysadmins (B<bostley>, B<jwfox>, and B<crawl>) may run any
|
|
command on any host but they must authenticate themselves first
|
|
(since the entry lacks the C<NOPASSWD> tag).
|
|
|
|
jack CSNETS = ALL
|
|
|
|
The user B<jack> may run any command on the machines in the I<CSNETS> alias
|
|
(the networks C<128.138.243.0>, C<128.138.204.0>, and C<128.138.242.0>).
|
|
Of those networks, only <128.138.204.0> has an explicit netmask (in
|
|
CIDR notation) indicating it is a class C network. For the other
|
|
networks in I<CSNETS>, the local machine's netmask will be used
|
|
during matching.
|
|
|
|
lisa CUNETS = ALL
|
|
|
|
The user B<lisa> may run any command on any host in the I<CUNETS> alias
|
|
(the class B network C<128.138.0.0>).
|
|
|
|
operator ALL = DUMPS, KILL, PRINTING, SHUTDOWN, HALT, REBOOT,\
|
|
/usr/oper/bin/
|
|
|
|
The B<operator> user may run commands limited to simple maintenance.
|
|
Here, those are commands related to backups, killing processes, the
|
|
printing system, shutting down the system, and any commands in the
|
|
directory F</usr/oper/bin/>.
|
|
|
|
joe ALL = /usr/bin/su operator
|
|
|
|
The user B<joe> may only su(1) to operator.
|
|
|
|
pete HPPA = /usr/bin/passwd [A-z]*, !/usr/bin/passwd root
|
|
|
|
The user B<pete> is allowed to change anyone's password except for
|
|
root on the I<HPPA> machines. Note that this assumes passwd(1)
|
|
does not take multiple usernames on the command line.
|
|
|
|
bob SPARC = (OP) ALL : SGI = (OP) ALL
|
|
|
|
The user B<bob> may run anything on the I<SPARC> and I<SGI> machines
|
|
as any user listed in the I<OP> C<Runas_Alias> (B<root> and B<operator>).
|
|
|
|
jim +biglab = ALL
|
|
|
|
The user B<jim> may run any command on machines in the I<biglab> netgroup.
|
|
B<Sudo> knows that "biglab" is a netgroup due to the '+' prefix.
|
|
|
|
+secretaries ALL = PRINTING, /usr/bin/adduser, /usr/bin/rmuser
|
|
|
|
Users in the B<secretaries> netgroup need to help manage the printers
|
|
as well as add and remove users, so they are allowed to run those
|
|
commands on all machines.
|
|
|
|
fred ALL = (DB) NOPASSWD: ALL
|
|
|
|
The user B<fred> can run commands as any user in the I<DB> C<Runas_Alias>
|
|
(B<oracle> or B<sybase>) without giving a password.
|
|
|
|
john ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root*
|
|
|
|
On the I<ALPHA> machines, user B<john> may su to anyone except root
|
|
but he is not allowed to give su(1) any flags.
|
|
|
|
jen ALL, !SERVERS = ALL
|
|
|
|
The user B<jen> may run any command on any machine except for those
|
|
in the I<SERVERS> C<Host_Alias> (master, mail, www and ns).
|
|
|
|
jill SERVERS = /usr/bin/, !SU, !SHELLS
|
|
|
|
For any machine in the I<SERVERS> C<Host_Alias>, B<jill> may run
|
|
any commands in the directory /usr/bin/ except for those commands
|
|
belonging to the I<SU> and I<SHELLS> C<Cmnd_Aliases>.
|
|
|
|
steve CSNETS = (operator) /usr/local/op_commands/
|
|
|
|
The user B<steve> may run any command in the directory /usr/local/op_commands/
|
|
but only as user operator.
|
|
|
|
matt valkyrie = KILL
|
|
|
|
On his personal workstation, valkyrie, B<matt> needs to be able to
|
|
kill hung processes.
|
|
|
|
WEBMASTERS www = (www) ALL, (root) /usr/bin/su www
|
|
|
|
On the host www, any user in the I<WEBMASTERS> C<User_Alias> (will,
|
|
wendy, and wim), may run any command as user www (which owns the
|
|
web pages) or simply su(1) to www.
|
|
|
|
ALL CDROM = NOPASSWD: /sbin/umount /CDROM,\
|
|
/sbin/mount -o nosuid\,nodev /dev/cd0a /CDROM
|
|
|
|
Any user may mount or unmount a CD-ROM on the machines in the CDROM
|
|
C<Host_Alias> (orion, perseus, hercules) without entering a password.
|
|
This is a bit tedious for users to type, so it is a prime candiate
|
|
for encapsulating in a shell script.
|
|
|
|
=head1 SECURITY NOTES
|
|
|
|
It is generally not effective to "subtract" commands from C<ALL>
|
|
using the '!' operator. A user can trivially circumvent this
|
|
by copying the desired command to a different name and then
|
|
executing that. For example:
|
|
|
|
bill ALL = ALL, !SU, !SHELLS
|
|
|
|
Doesn't really prevent B<bill> from running the commands listed in
|
|
I<SU> or I<SHELLS> since he can simply copy those commands to a
|
|
different name, or use a shell escape from an editor or other
|
|
program. Therefore, these kind of restrictions should be considered
|
|
advisory at best (and reinforced by policy).
|
|
|
|
=head1 CAVEATS
|
|
|
|
The I<sudoers> file should B<always> be edited by the B<visudo>
|
|
command which locks the file and does grammatical checking. It is
|
|
imperative that I<sudoers> be free of syntax errors since B<sudo>
|
|
will not run with a syntactically incorrect I<sudoers> file.
|
|
|
|
=head1 FILES
|
|
|
|
/etc/sudoers List of who can run what
|
|
/etc/group Local groups file
|
|
/etc/netgroup List of network groups
|
|
|
|
=head1 SEE ALSO
|
|
|
|
sudo(8), visudo(8), su(1), fnmatch(3).
|