sudoers - list of which users may execute what
The sudoers file is composed of two types of entries: aliases (basically variables) and user specifications (which specify who may run what). The grammar of 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.
EBNF is a concise and exact way of describing the grammar of a language. Each EBNF definition is made up of production rules. E.g.,
symbol ::= definition | alternate1 | alternate2 ...
Each 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.
?
+
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).
There are four kinds of aliases: User_Alias
, Runas_Alias
,
Host_Alias
and Cmnd_Alias
.
Alias ::= 'User_Alias' User_Alias (':' User_Alias)* | 'Runas_Alias' Runas_Alias (':' Runas_Alias)* | 'Host_Alias' Host_Alias (':' Host_Alias)* | 'Cmnd_Alias' Cmnd_Alias (':' Cmnd_Alias)*
User_Alias ::= NAME '=' User_List
Runas_Alias ::= NAME '=' Runas_List
Host_Alias ::= NAME '=' Host_List
Cmnd_Alias ::= NAME '=' Cmnd_List
NAME ::= [A-Z]([A-Z][0-9]_)*
Each alias definition is of the form
Alias_Type NAME = item1, item2, ...
where Alias_Type is one of User_Alias
,
Runas_Alias
, Host_Alias
, or Cmnd_Alias
. A
NAME
is a string of uppercase letters, numbers, and underscore characters
('_'). A NAME
must start with an uppercase letter.
It is possible to put several alias definitions of the same type on a single
line, joined by a colon (':'). E.g.,
Alias_Type NAME = item1, item2, item3 : NAME = item4, item5
The definitions of what constitutes a valid alias member follow.
User_List ::= User | User ',' User_List
User ::= '!'* username | '!'* '%'group | '!'* '+'netgroup | '!'* User_Alias
A 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 negate 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
A Runas_List
is similar to a User_List
except that
it can also contain uids (prefixed with '#') and instead of User_Alias
es
it can contain Runas_Alias
es.
Host_List ::= Host | Host ',' Host_List
Host ::= '!'* hostname | '!'* ip_addr | '!'* network(/netmask)? | '!'* '+'netgroup | '!'* Host_Alias
A 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 (e.g. 255.255.255.0) or CIDR notation (number of
bits, e.g. 24). A hostname may include shell-style wildcards (see `Wildcards'
section below), but unless the hostname
command on your machine
returns the fully qualified hostname, you'll need to use the fqdn
option for wildcards to be useful.
Cmnd_List ::= Cmnd | Cmnd ',' Cmnd_List
commandname ::= filename | filename args | filename '""'
Cmnd ::= '!'* commandname | '!'* directory | '!'* Cmnd_Alias
A 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 specify command line arguments (including wildcards). Alternately, you can
specify ""
to indicate that the command may only be run without command
line arguments. A directory is a fully qualified pathname ending in a '/'. When
you specify a directory in a Cmnd_List
, the user will be able to
run any file within that directory (but not in any subdirectories therein).
If a Cmnd
has associated command line arguments, then the
arguments in the 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: ',', ':', '=', '\'.
Certain configuration options may be changed from their default values at
runtime via one or more Default_Entry
lines. These may affect all
users on any host, all users on a specific host, a specific user, or commands
being run as a specific user. When multiple entries match, they are applied in
order. Where there are conflicting values, the last value on a matching line
takes effect.
Default_Type ::= 'Defaults' || 'Defaults' '@' Host || 'Defaults' ':' User || 'Defaults' '>' RunasUser
Default_Entry ::= Default_Type Parameter_List
Parameter ::= Parameter '=' Value || Parameter '+=' Value || Parameter '-=' Value || '!'* Parameter ||
Parameters may be flags, integer values,
strings, or lists. Flags are implicitly
boolean and can be turned off via the '!' operator. Some integer, string and
list parameters may also be used in a boolean context to disable them. Values
may be enclosed in double quotes ("
) when they contain multiple
words. Special characters may be escaped with a backslash (\
).
Lists have two additional assignment operators, +=
and -=
.
These operators are used to add to and delete from a list respectively. It is
not an error to use the -=
operator to remove an element that does
not exist in a list.
Note that since the sudoers file is parsed in order the best place to put the Defaults section is after the Host, User, and Cmnd aliases but before the user specifications.
Flags:
PATH
environment variable; the PATH
itself is not
modified. This flag is off by default.
PASSWD
and NOPASSWD
tags. This
flag is on by default.
"sudo sudo /bin/sh"
. This flag is
on by default.
SHELL
environment variable
if it is set, falling back on the shell listed in the invoking user's /etc/passwd
entry if not). This flag is off by default.
HOME
environment variable will be set to the home
directory of the target user (which is root unless the -u
option is used). This effectively makes the -s flag imply
-H. This flag is off by default.
HOME
environment
variable to the home directory of the target user (which is root unless the
-u option is used). This effectively means that the
-H flag is always implied. This flag is off by default.
PATH
environment variable. Some sites may
wish to disable this as it could be used to gather information on the location
of executables that the normal user does not have access to. The disadvantage
is that if the executable is simply not in the user's PATH
,
sudo will tell the user that they are not allowed to run it,
which can be confusing. This flag is off by default.
CNAME
entry) due to performance issues and the
fact that there is no way to get all aliases from DNS. If your machine's
hostname (as returned by the hostname
command) is already fully
qualified you shouldn't need to set fqdn. This flag is off
by default.
"rsh somehost sudo ls"
since rsh(1)
does not allocate a tty. Because it is not possible
to turn off echo when there is no tty present, some sites may with to set this
flag to prevent a user from entering a visible password. This flag is off
by default.
editor
variable. visudo will then only use the EDITOR or VISUAL if
they match a value specified in
editor
.
This flag is off
by default.
root
)
instead of the password of the invoking user. This flag is off by
default.
root
)
instead of the password of the invoking user. This flag is off by
default.
LOGNAME
and
USER
environment variables to the name of the target user
(usually root unless the -u flag is given). However, since
some programs (including the RCS revision control system) use LOGNAME
to determine the real identity of the user, it may be desirable to change this
behavior. This can be done by negating the set_logname option.
HOME
, LOGNAME
, PATH
,
SHELL
, TERM
, and USER
(in addition to
the SUDO_
variables). Of these, only TERM
is copied
unaltered from the old environment. The other variables are set to default
values (possibly modified by the value of the set_logname option). If
sudo was compiled with the SECURE_PATH
option,
its value will be used for the PATH
environment variable. Other
variables may be preserved with the env_keep option.
Integers:
3
.
Integers that can be used in a boolean context:
80
(use 0 or
negate the option to disable word wrap).
5
. Set this to 0
to always prompt for a password. If set to a value less than 0
the user's timestamp will never expire. This can be used to allow users to
create or delete their own timestamps via sudo -v
and sudo
-k
respectively.
5
, set this to 0
for no password
timeout.
022
.
Strings:
%h
will
expand to the hostname of the machine. Default is *** SECURITY
information for %h ***
.
Sorry, try again.
unless insults are enabled.
root
.
SUDO_PROMPT
environment
variable. The following percent (`%
') escapes are supported:
%u
%U
%h
%H
%%
%
characters are collaped into a single
%
character
The default value is Password:
.
root
.
notice
.
alert
.
Strings that can be used in a boolean context:
local2
.
"
) to protect against sudo interpreting the
@
sign. Defaults to root
.
NOPASSWD
flag set to avoid entering a password.
NOPASSWD
flag set to avoid entering a password.
The default value is `all'.
NOPASSWD
flag set to avoid entering a password.
NOPASSWD
flag set to avoid entering a password.
The default value is `any'.
Lists that can be used in a boolean context:
%
or /
characters. This
can be used to guard against printf-style format vulnerabilities in
poorly-written programs. The argument may be a double-quoted, space-separated
list or a single value without double-quotes. The list can be replaced, added
to, deleted from, or disabled by using the =
, +=
,
-=
, and !
operators respectively. The default list
of environment variables to check is printed when sudo is run
by root with the -V option.
=
, +=
, -=
, and
!
operators respectively. The default list of environment
variables to remove is printed when sudo is run by root with
the -V option. Note that many operating systems will remove
potentially dangerous variables from the environment of any setuid process
(such as sudo).
=
, +=
, -=
, and
!
operators respectively. This list has no default members.
When logging via syslog(3), sudo accepts the following values for the syslog facility (the value of the syslog Parameter): authpriv (if your OS supports it), auth, daemon, user, local0, local1, local2, local3, local4, local5, local6, and local7. The following syslog priorities are supported: alert, crit, debug, emerg, err, info, notice, and B.
User_Spec ::= User_list Host_List '=' Cmnd_Spec_List \ (':' User_Spec)*
Cmnd_Spec_List ::= Cmnd_Spec | Cmnd_Spec ',' Cmnd_Spec_List
Cmnd_Spec ::= Runas_Spec? ('NOPASSWD:' | 'PASSWD:')? Cmnd
Runas_Spec ::= '(' Runas_List ')'
A user specification determines which commands a user may run (and as what user) on specified hosts. By default, commands are run as root, but this can be changed on a per-command basis.
Let's break that down into its constituent parts:
A Runas_Spec
is simply a Runas_List
(as defined
above) enclosed in a set of parentheses. If you do not specify a
Runas_Spec
in the user specification, a default Runas_Spec
of root will be used. A 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/lprm
The user dgb may run /bin/ls, /bin/kill, and /usr/bin/lprm -- but only as operator. E.g.,
sudo -u operator /bin/ls.
It is also possible to override a 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 dgb is now allowed to run /bin/ls as operator, but /bin/kill and /usr/bin/lprm as root.
By default, sudo requires that a user authenticate him or
herself before running a command. This behavior can be modified via the
NOPASSWD
tag. Like a Runas_Spec
, the NOPASSWD
tag sets a default for the commands that follow it in the Cmnd_Spec_List
.
Conversely, the PASSWD
tag can be used to reverse things. For
example:
ray rushmore = NOPASSWD: /bin/kill, /bin/ls, /usr/bin/lprm
would allow the user ray to run /bin/kill, /bin/ls, and /usr/bin/lprm as root on the machine rushmore as root without authenticating himself. If we only want ray to be able to run /bin/kill without a password the entry would be:
ray rushmore = NOPASSWD: /bin/kill, PASSWD: /bin/ls, /usr/bin/lprm
Note, however, that the PASSWD
tag has no effect on users who
are in the group specified by the exempt_group option.
By default, if the NOPASSWD
tag is applied to any of the entries
for a user on the current host, he or she will be able to run sudo -l
without a password. Additionally, a user may only run sudo -v
without a password if the NOPASSWD
tag is present for all a user's
entries that pertain to the current host. This behavior may be overridden via
the verifypw and listpw options.
sudo allows shell-style wildcards to be used in
pathnames as well as command line arguments in the sudoers file.
Wildcard matching is done via the POSIX fnmatch(3)
routine. Note that these are not regular expressions.
?
[...]
[!...]
\x
Note that a forward slash ('/') will not be matched by wildcards used in the pathname. When matching the command line arguments, however, a slash does get matched by wildcards. This is to make a path like:
/usr/bin/*
match /usr/bin/who
but not /usr/bin/X11/xterm
.
The following exceptions apply to the above rules:
""
""
is the only command line argument in the sudoers entry it means that
command is not allowed to be run with any arguments.
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 ALL is a built in alias that
always causes a match to succeed. It can be used wherever one might otherwise
use a Cmnd_Alias
, User_Alias
, Runas_Alias
,
or Host_Alias
. You should not try to define your own alias
called ALL as the built in alias will be used in preference to
your own. Please note that using ALL can be dangerous since in
a command context, it allows the user to run any command on the
system.
An exclamation point ('!') can be used as a logical not operator
both in an alias and in front of a Cmnd
. This allows one
to exclude certain values. Note, however, that using a !
in
conjunction with the built in 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 special syntactic characters in a User Specification ('=', ':', '(', ')') is optional.
The following characters must be escaped with a backslash ('\') when used as part of a word (e.g. a username or hostname): '@', '!', '=', ':', ',', '(', ')', '\'.
Below are example sudoers entries. Admittedly, some of these are a bit contrived. First, we define our aliases:
User_Alias FULLTIMERS = millert, mikef, dowdy User_Alias PARTTIMERS = bostley, jwfox, crawl User_Alias WEBMASTERS = will, wendy, wim
Runas_Alias OP = root, operator Runas_Alias DB = oracle, sybase
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 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
Here we override some of the compiled in default values. We want sudo
to log via syslog(3)
using the auth facility in all cases. We don't want to subject the full
time staff to the sudo lecture, user millert
need not give a password, and we don't want to set the LOGNAME
or
USER
environment variables when running commands as root.
Additionally, on the machines in the SERVERS Host_Alias
,
we keep an additional local log file and make sure we log the year in each log
line since the log entries will be kept around for several years.
Defaults syslog=auth Defaults>root !set_logname Defaults:FULLTIMERS !lecture Defaults:millert !authenticate Defaults@SERVERS log_year, logfile=/var/log/sudo.log
The User specification is the part that actually determines who may run what.
root ALL = (ALL) ALL %wheel ALL = (ALL) ALL
We let root and any user in group wheel run any command on any host as any user.
FULLTIMERS ALL = NOPASSWD: ALL
Full time sysadmins (millert, mikef, and dowdy) may run any command on any host without authenticating themselves.
PARTTIMERS ALL = ALL
Part time sysadmins (bostley, jwfox, and
crawl) may run any command on any host but they must
authenticate themselves first (since the entry lacks the NOPASSWD
tag).
jack CSNETS = ALL
The user jack may run any command on the machines in the
CSNETS alias (the networks 128.138.243.0
, 128.138.204.0
,
and 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 CSNETS, the local machine's netmask will be
used during matching.
lisa CUNETS = ALL
The user lisa may run any command on any host in the
CUNETS alias (the class B network 128.138.0.0
).
operator ALL = DUMPS, KILL, PRINTING, SHUTDOWN, HALT, REBOOT,\ /usr/oper/bin/
The 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 /usr/oper/bin.
joe ALL = /usr/bin/su operator
The user joe may only su(1)
to operator.
pete HPPA = /usr/bin/passwd [A-z]*, !/usr/bin/passwd root
The user pete is allowed to change anyone's password except
for root on the 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 bob may run anything on the SPARC and
SGI machines as any user listed in the OP Runas_Alias
(root and operator).
jim +biglab = ALL
The user jim may run any command on machines in the biglab netgroup. Sudo knows that ``biglab'' is a netgroup due to the '+' prefix.
+secretaries ALL = PRINTING, /usr/bin/adduser, /usr/bin/rmuser
Users in the 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 fred can run commands as any user in the DB
Runas_Alias
(oracle or sybase)
without giving a password.
john ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root*
On the ALPHA machines, user john may su to anyone
except root but he is not allowed to give su(1)
any flags.
jen ALL, !SERVERS = ALL
The user jen may run any command on any machine except for
those in the SERVERS Host_Alias
(master, mail, www and
ns).
jill SERVERS = /usr/bin/, !SU, !SHELLS
For any machine in the SERVERS Host_Alias
, jill
may run any commands in the directory /usr/bin/ except for those commands
belonging to the SU and SHELLS Cmnd_Aliases
.
steve CSNETS = (operator) /usr/local/op_commands/
The user 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, 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 WEBMASTERS 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
Host_Alias
(orion, perseus, hercules) without entering a password. This
is a bit tedious for users to type, so it is a prime candidate for encapsulating
in a shell script.
It is generally not effective to ``subtract'' commands from 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 bill from running the commands listed in SU or 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).
The sudoers file should always be edited by the visudo command which locks the file and does grammatical checking. It is imperative that sudoers be free of syntax errors since sudo will not run with a syntactically incorrect sudoers file.
When using netgroups of machines (as opposed to users), if you store fully
qualified hostnames in the netgroup (as is usually the case), you either need to
have the machine's hostname be fully qualified as returned by the hostname
command or use the fqdn option in sudoers.
/etc/sudoers List of who can run what /etc/group Local groups file /etc/netgroup List of network groups
첫댓글 http://www.sudo.ws/sudo/man/sudoers.html