Путеводитель по Руководству Linux

  User  |  Syst  |  Libr  |  Device  |  Files  |  Other  |  Admin  |  Head  |



   sudoers    ( 5 )

плагин политики безопасности sudo по умолчанию (default sudo security policy plugin)

SUDOERS FILE FORMAT

The sudoers file is composed of two types of entries: aliases
     (basically variables) and user specifications (which specify who
     may run what).

When multiple entries match for a user, they are applied in order. Where there are multiple matches, the last match is used (which is not necessarily the most specific match).

The sudoers file grammar will be described below in Extended Backus-Naur Form (EBNF). Don't despair if you are unfamiliar with EBNF; it is fairly simple, and the definitions below are annotated.

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 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.

? Means that the preceding symbol (or group of symbols) is optional. That is, it may appear once or not at all.

* Means that the preceding symbol (or group of symbols) may appear zero or more times.

+ Means that the preceding symbol (or group of symbols) may appear one or more times.

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).

Aliases There are four kinds of aliases: User_Alias, Runas_Alias, Host_Alias and Cmnd_Alias. Beginning with sudo 1.9.0, Cmd_Alias may be used in place of Cmnd_Alias if desired.

Alias ::= 'User_Alias' User_Alias_Spec (':' User_Alias_Spec)* | 'Runas_Alias' Runas_Alias_Spec (':' Runas_Alias_Spec)* | 'Host_Alias' Host_Alias_Spec (':' Host_Alias_Spec)* | 'Cmnd_Alias' Cmnd_Alias_Spec (':' Cmnd_Alias_Spec)* | 'Cmd_Alias' Cmnd_Alias_Spec (':' Cmnd_Alias_Spec)*

User_Alias ::= NAME

User_Alias_Spec ::= User_Alias '=' User_List

Runas_Alias ::= NAME

Runas_Alias_Spec ::= Runas_Alias '=' Runas_List

Host_Alias ::= NAME

Host_Alias_Spec ::= Host_Alias '=' Host_List

Cmnd_Alias ::= NAME

Cmnd_Alias_Spec ::= Cmnd_Alias '=' 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

It is a syntax error to redefine an existing alias. It is possible to use the same name for aliases of different types, but this is not recommended.

The definitions of what constitutes a valid alias member follow.

User_List ::= User | User ',' User_List

User ::= '!'* user name | '!'* #uid | '!'* %group | '!'* %#gid | '!'* +netgroup | '!'* %:nonunix_group | '!'* %:#nonunix_gid | '!'* User_Alias

A User_List is made up of one or more user names, user-IDs (prefixed with '#'), system group names and IDs (prefixed with '%' and '%#' respectively), netgroups (prefixed with '+'), non-Unix group names and IDs (prefixed with '%:' and '%:#' respectively) and User_Aliases. Each list item may be prefixed with zero or more '!' operators. An odd number of '!' operators negate the value of the item; an even number just cancel each other out. User netgroups are matched using the user and domain members only; the host member is not used when matching.

A user name, uid, group, gid, netgroup, nonunix_group or nonunix_gid may be enclosed in double quotes to avoid the need for escaping special characters. Alternately, special characters may be specified in escaped hex mode, e.g., \x20 for space. When using double quotes, any prefix characters must be included inside the quotes.

The actual nonunix_group and nonunix_gid syntax depends on the underlying group provider plugin. For instance, the QAS AD plugin supports the following formats:

Group in the same domain: "%:Group Name"

Group in any domain: "%:Group Name@FULLY.QUALIFIED.DOMAIN"

Group SID: "%:S-1-2-34-5678901234-5678901234-5678901234-567"

See GROUP PROVIDER PLUGINS for more information.

Note that quotes around group names are optional. Unquoted strings must use a backslash ('\') to escape spaces and special characters. See Other special characters and reserved words for a list of characters that need to be escaped.

Runas_List ::= Runas_Member | Runas_Member ',' Runas_List

Runas_Member ::= '!'* user name | '!'* #uid | '!'* %group | '!'* %#gid | '!'* %:nonunix_group | '!'* %:#nonunix_gid | '!'* +netgroup | '!'* Runas_Alias

A Runas_List is similar to a User_List except that instead of User_Aliases it can contain Runas_Aliases. Note that user names and groups are matched as strings. In other words, two users (groups) with the same user (group) ID are considered to be distinct. If you wish to match all user names with the same user- ID (e.g., root and toor), you can use a user-ID instead of a name (#0 in the example given). Note that the user-ID or group-ID specified in a Runas_Member need not be listed in the password or group database.

Host_List ::= Host | Host ',' Host_List

Host ::= '!'* host name | '!'* ip_addr | '!'* network(/netmask)? | '!'* +netgroup | '!'* Host_Alias

A Host_List is made up of one or more host names, IP addresses, network numbers, netgroups (prefixed with '+') and other aliases. Again, the value of an item may be negated with the '!' operator. Host netgroups are matched using the host (both qualified and unqualified) and domain members only; the user member is not used when matching. If you specify a network number without a netmask, sudo will query each of the local host's network interfaces and, if the network number corresponds to one of the hosts's network interfaces, will use the netmask of that interface. The netmask may be specified either in standard IP address notation (e.g., 255.255.255.0 or ffff:ffff:ffff:ffff::), or CIDR notation (number of bits, e.g., 24 or 64). A host name may include shell-style wildcards (see the Wildcards section below), but unless the host name command on your machine returns the fully qualified host name, you'll need to use the fqdn flag for wildcards to be useful. Note that sudo only inspects actual network interfaces; this means that IP address 127.0.0.1 (localhost) will never match. Also, the host name 'localhost' will only match if that is the actual host name, which is usually only the case for non-networked systems.

digest ::= [A-Fa-f0-9]+ | [A-Za-z0-9\+/=]+

Digest_Spec ::= "sha224" ':' digest | "sha256" ':' digest | "sha384" ':' digest | "sha512" ':' digest

Digest_List ::= Digest_Spec | Digest_Spec ',' Digest_List

Cmnd_List ::= Cmnd | Cmnd ',' Cmnd_List

command name ::= file name | file name args | file name '""'

Edit_Spec ::= "sudoedit" file name+

Cmnd ::= Digest_List? '!'* command name | '!'* directory | '!'* Edit_Spec | '!'* Cmnd_Alias

A Cmnd_List is a list of one or more command names, directories, and other aliases. A command name is a fully qualified file name which may include shell-style wildcards (see the Wildcards section below). A simple file name allows the user to run the command with any arguments they wish. 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 path name 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 sub-directories 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: ',', ':', '=', '\'. The built-in command 'sudoedit' is used to permit a user to run sudo with the -e option (or as sudoedit). It may take command line arguments just as a normal command does. Note that 'sudoedit' is a command built into sudo itself and must be specified in the sudoers file without a leading path. If a leading path is present, for example /usr/bin/sudoedit, the path name will be silently converted to 'sudoedit'. A fully-qualified path for sudoedit is treated as an error by visudo.

A command name may be preceded by a Digest_List, a comma-separated list of one or more Digest_Spec entries. If a Digest_List is present, the command will only match successfully if it can be verified using one of the SHA-2 digests in the list. Starting with version 1.9.0, the ALL reserved word can be used in conjunction with a Digest_List. The following digest formats are supported: sha224, sha256, sha384 and sha512. The string may be specified in either hex or base64 format (base64 is more compact). There are several utilities capable of generating SHA-2 digests in hex format such as openssl, shasum, sha224sum, sha256sum, sha384sum, sha512sum.

For example, using openssl:

$ openssl dgst -sha224 /bin/ls SHA224(/bin/ls)= 118187da8364d490b4a7debbf483004e8f3e053ec954309de2c41a25

It is also possible to use openssl to generate base64 output:

$ openssl dgst -binary -sha224 /bin/ls | openssl base64 EYGH2oNk1JC0p9679IMATo8+BT7JVDCd4sQaJQ==

Warning, if the user has write access to the command itself (directly or via a sudo command), it may be possible for the user to replace the command after the digest check has been performed but before the command is executed. A similar race condition exists on systems that lack the fexecve() system call when the directory in which the command is located is writable by the user. See the description of the fdexec setting for more information on how sudo executes commands that have an associated digest.

Command digests are only supported by version 1.8.7 or higher.

Defaults Certain configuration options may be changed from their default values at run-time via one or more Default_Entry lines. These may affect all users on any host, all users on a specific host, a specific user, a specific command, or commands being run as a specific user. Note that per-command entries may not include command line arguments. If you need to specify arguments, define a Cmnd_Alias and reference that instead.

Default_Type ::= 'Defaults' | 'Defaults' '@' Host_List | 'Defaults' ':' User_List | 'Defaults' '!' Cmnd_List | 'Defaults' '>' Runas_List

Default_Entry ::= Default_Type Parameter_List

Parameter_List ::= Parameter | Parameter ',' 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 ('\').

To include a literal backslash character in a command line argument you must escape the backslash twice. For example, to match '\n' as part of a command line argument, you must use '\\\\n' in the sudoers file. This is due to there being two levels of escaping, one in the sudoers parser itself and another when command line arguments are matched by the fnmatch(3) function.

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.

Defaults entries are parsed in the following order: generic, host, user and runas Defaults first, then command defaults. If there are multiple Defaults settings of the same type, the last matching setting is used. The following Defaults settings are parsed before all others since they may affect subsequent entries: fqdn, group_plugin, runas_default, sudoers_locale.

See SUDOERS OPTIONS for a list of supported Defaults parameters.

User specification User_Spec ::= User_List Host_List '=' Cmnd_Spec_List \ (':' Host_List '=' Cmnd_Spec_List)*

Cmnd_Spec_List ::= Cmnd_Spec | Cmnd_Spec ',' Cmnd_Spec_List

Cmnd_Spec ::= Runas_Spec? Option_Spec* Tag_Spec* Cmnd

Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'

Option_Spec ::= (Date_Spec | Timeout_Spec | Chdir_Spec | Chroot_Spec)

Date_Spec ::= ('NOTBEFORE=timestamp' | 'NOTAFTER=timestamp')

Timeout_Spec ::= 'TIMEOUT=timeout'

Chdir_Spec ::= 'CWD=directory'

Chroot_Spec ::= 'CHROOT=directory'

Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' | 'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' | 'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' | 'INTERCEPT:' | 'NOINTERCEPT:' | 'PASSWD:' | 'NOPASSWD:' | 'SETENV:' | 'NOSETENV:')

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.

The basic structure of a user specification is 'who where = (as_whom) what'. Let's break that down into its constituent parts:

Runas_Spec A Runas_Spec determines the user and/or the group that a command may be run as. A fully-specified Runas_Spec consists of two Runas_Lists (as defined above) separated by a colon (':') and enclosed in a set of parentheses. The first Runas_List indicates which users the command may be run as via the -u option. The second defines a list of groups that may be specified via the -g option (in addition to any of the target user's groups). If both Runas_Lists are specified, the command may be run with any combination of users and groups listed in their respective Runas_Lists. If only the first is specified, the command may be run as any user in the list and, optionally, with any group the target user belongs to. If the first Runas_List is empty but the second is specified, the command may be run as the invoking user with the group set to any listed in the Runas_List. If both Runas_Lists are empty, the command may only be run as the invoking user and the group, if specified, must be one that the invoking user is a member of. If no Runas_Spec is specified, the command may only be run as root and the group, if specified, must be one that root is a member of.

A Runas_Spec sets the default for the 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 on the host boulder—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.

We can extend this to allow dgb to run /bin/ls with either the user or group set to operator:

dgb boulder = (operator : operator) /bin/ls, (root) /bin/kill,\ /usr/bin/lprm

Note that while the group portion of the Runas_Spec permits the user to run as command with that group, it does not force the user to do so. If no group is specified on the command line, the command will run with the group listed in the target user's password database entry. The following would all be permitted by the sudoers entry above:

$ sudo -u operator /bin/ls $ sudo -u operator -g operator /bin/ls $ sudo -g operator /bin/ls

In the following example, user tcm may run commands that access a modem device file with the dialer group.

tcm boulder = (:dialer) /usr/bin/tip, /usr/bin/cu,\ /usr/local/bin/minicom

Note that in this example only the group will be set, the command still runs as user tcm. E.g.

$ sudo -g dialer /usr/bin/cu

Multiple users and groups may be present in a Runas_Spec, in which case the user may select any combination of users and groups via the -u and -g options. In this example:

alan ALL = (root, bin : operator, system) ALL

user alan may run any command as either user root or bin, optionally setting the group to operator or system.

Option_Spec A Cmnd may have zero or more options associated with it. Options may consist of start and/or end dates and command timeouts. Once an option is set for a Cmnd, subsequent Cmnds in the Cmnd_Spec_List, inherit that option unless it is overridden by another option. Note that the option names are reserved words in sudoers. This means that none of the valid option names (see below) can be used when declaring an alias.

Date_Spec sudoers rules can be specified with a start and end date via the NOTBEFORE and NOTAFTER settings. The time stamp must be specified in Generalized Time as defined by RFC 4517. The format is effectively yyyymmddHHMMSSZ where the minutes and seconds are optional. The 'Z' suffix indicates that the time stamp is in Coordinated Universal Time (UTC). It is also possible to specify a timezone offset from UTC in hours and minutes instead of a 'Z'. For example, '-0500' would correspond to Eastern Standard time in the US. As an extension, if no 'Z' or timezone offset is specified, local time will be used.

The following are all valid time stamps:

20170214083000Z 2017021408Z 20160315220000-0500 20151201235900

Timeout_Spec A command may have a timeout associated with it. If the timeout expires before the command has exited, the command will be terminated. The timeout may be specified in combinations of days, hours, minutes and seconds with a single-letter case-insensitive suffix that indicates the unit of time. For example, a timeout of 7 days, 8 hours, 30 minutes and 10 seconds would be written as 7d8h30m10s. If a number is specified without a unit, seconds are assumed. Any of the days, minutes, hours or seconds may be omitted. The order must be from largest to smallest unit and a unit may not be specified more than once.

The following are all valid timeout values: 7d8h30m10s, 14d, 8h30m, 600s, 3600. The following are invalid timeout values: 12m2w1d, 30s10m4h, 1d2d3h.

This setting is only supported by version 1.8.20 or higher.

Chdir_Spec The working directory that the command will be run in can be specified using the CWD setting. The directory must be a fully- qualified path name beginning with a '/' or '~' character, or the special value '*'. A value of '*' indicates that the user may specify the working directory by running sudo with the -D option. By default, commands are run from the invoking user's current working directory, unless the -i option is given. Path names of the form ~user/path/name are interpreted as being relative to the named user's home directory. If the user name is omitted, the path will be relative to the runas user's home directory.

This setting is only supported by version 1.9.3 or higher.

Chroot_Spec The root directory that the command will be run in can be specified using the CHROOT setting. The directory must be a fully-qualified path name beginning with a '/' or '~' character, or the special value '*'. A value of '*' indicates that the user may specify the root directory by running sudo with the -R option. This setting can be used to run the command in a chroot(2) 'sandbox' similar to the chroot(8) utility. Path names of the form ~user/path/name are interpreted as being relative to the named user's home directory. If the user name is omitted, the path will be relative to the runas user's home directory.

This setting is only supported by version 1.9.3 or higher.

Tag_Spec A command may have zero or more tags associated with it. The following tag values are supported: EXEC, NOEXEC, FOLLOW, NOFOLLOW, LOG_INPUT, NOLOG_INPUT, LOG_OUTPUT, NOLOG_OUTPUT, MAIL, NOMAIL, INTERCEPT, NOINTERCEPT, PASSWD, NOPASSWD, SETENV, and NOSETENV. Once a tag is set on a Cmnd, subsequent Cmnds in the Cmnd_Spec_List, inherit the tag unless it is overridden by the opposite tag (in other words, PASSWD overrides NOPASSWD and NOEXEC overrides EXEC).

EXEC and NOEXEC

If sudo has been compiled with noexec support and the underlying operating system supports it, the NOEXEC tag can be used to prevent a dynamically-linked executable from running further commands itself.

In the following example, user aaron may run /usr/bin/more and /usr/bin/vi but shell escapes will be disabled.

aaron shanty = NOEXEC: /usr/bin/more, /usr/bin/vi

See the Preventing shell escapes section below for more details on how NOEXEC works and whether or not it will work on your system.

FOLLOW and NOFOLLOW Starting with version 1.8.15, sudoedit will not open a file that is a symbolic link unless the sudoedit_follow flag is enabled. The FOLLOW and NOFOLLOW tags override the value of sudoedit_follow and can be used to permit (or deny) the editing of symbolic links on a per-command basis. These tags are only effective for the sudoedit command and are ignored for all other commands.

LOG_INPUT and NOLOG_INPUT

These tags override the value of the log_input flag on a per- command basis. For more information, see the description of log_input in the SUDOERS OPTIONS section below.

LOG_OUTPUT and NOLOG_OUTPUT

These tags override the value of the log_output flag on a per- command basis. For more information, see the description of log_output in the SUDOERS OPTIONS section below.

MAIL and NOMAIL

These tags provide fine-grained control over whether mail will be sent when a user runs a command by overriding the value of the mail_all_cmnds flag on a per-command basis. They have no effect when sudo is run with the -l or -v options. A NOMAIL tag will also override the mail_always and mail_no_perms options. For more information, see the descriptions of mail_all_cmnds, mail_always, and mail_no_perms in the SUDOERS OPTIONS section below.

PASSWD and NOPASSWD

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' 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 setting.

By default, if the NOPASSWD tag is applied to any of a user's entries for the current host, the user will be able to run 'sudo -l' without a password. Additionally, a user may only run 'sudo -v' without a password if all of the user's entries for the current host have the NOPASSWD tag. This behavior may be overridden via the verifypw and listpw options.

SETENV and NOSETENV

These tags override the value of the setenv flag on a per-command basis. Note that if SETENV has been set for a command, the user may disable the env_reset flag from the command line via the -E option. Additionally, environment variables set on the command line are not subject to the restrictions imposed by env_check, env_delete, or env_keep. As such, only trusted users should be allowed to set variables in this manner. If the command matched is ALL, the SETENV tag is implied for that command; this default may be overridden by use of the NOSETENV tag.

INTERCEPT and NOINTERCEPT

If sudo has been compiled with intercept support and the underlying operating system supports it, the INTERCEPT tag can be used to cause programs spawned by a command to be validated against sudoers and logged just like they would be if run through sudo directly. This is useful in conjunction with commands that allow shell escapes such as editors, shells and paginators.

In the following example, user chuck may run any command on the machine 'research' in intercept mode.

chuck research = INTERCEPT: ALL

See the Preventing shell escapes section below for more details on how INTERCEPT works and whether or not it will work on your system.

Wildcards sudo allows shell-style wildcards (aka meta or glob characters) to be used in host names, path names and command line arguments in the sudoers file. Wildcard matching is done via the glob(3) and fnmatch(3) functions as specified by IEEE Std 1003.1 ('POSIX.1').

* Matches any set of zero or more characters (including white space).

? Matches any single character (including white space).

[...] Matches any character in the specified range.

[!...] Matches any character not in the specified range.

\x For any character 'x', evaluates to 'x'. This is used to escape special characters such as: '*', '?', '[', and ']'.

Note that these are not regular expressions. Unlike a regular expression there is no way to match one or more characters within a range.

Character classes may be used if your system's glob(3) and fnmatch(3) functions support them. However, because the ':' character has special meaning in sudoers, it must be escaped. For example:

/bin/ls [[\:alpha\:]]*

Would match any file name beginning with a letter.

Note that a forward slash ('/') will not be matched by wildcards used in the file name portion of the command. This is to make a path like:

/usr/bin/*

match /usr/bin/who but not /usr/bin/X11/xterm.

When matching the command line arguments, however, a slash does get matched by wildcards since command line arguments may contain arbitrary strings and not just path names.

Wildcards in command line arguments should be used with care. Command line arguments are matched as a single, concatenated string. This mean a wildcard character such as '?' or '*' will match across word boundaries, which may be unexpected. For example, while a sudoers entry like:

%operator ALL = /bin/cat /var/log/messages*

will allow command like:

$ sudo cat /var/log/messages.1

It will also allow:

$ sudo cat /var/log/messages /etc/shadow

which is probably not what was intended. In most cases it is better to do command line processing outside of the sudoers file in a scripting language.

Exceptions to wildcard rules The following exceptions apply to the above rules:

"" If the empty string "" is the only command line argument in the sudoers file entry it means that command is not allowed to be run with any arguments.

sudoedit Command line arguments to the sudoedit built-in command should always be path names, so a forward slash ('/') will not be matched by a wildcard.

Including other files from within sudoers It is possible to include other sudoers files from within the sudoers file currently being parsed using the @include and @includedir directives. For compatibility with sudo versions prior to 1.9.1, #include and #includedir are also accepted.

An include file can be used, for example, to keep a site-wide sudoers file in addition to a local, per-machine file. For the sake of this example the site-wide sudoers file will be /etc/sudoers and the per-machine one will be /etc/sudoers.local. To include /etc/sudoers.local from within /etc/sudoers one would use the following line in /etc/sudoers:

@include /etc/sudoers.local

When sudo reaches this line it will suspend processing of the current file (/etc/sudoers) and switch to /etc/sudoers.local. Upon reaching the end of /etc/sudoers.local, the rest of /etc/sudoers will be processed. Files that are included may themselves include other files. A hard limit of 128 nested include files is enforced to prevent include file loops.

The path to the include file may contain white space if it is escaped with a backslash ('\'). Alternately, the entire path may be enclosed in double quotes (""), in which case no escaping is necessary. To include a literal backslash in the path, '\\' should be used.

If the path to the include file is not fully-qualified (does not begin with a '/'), it must be located in the same directory as the sudoers file it was included from. For example, if /etc/sudoers contains the line:

@include sudoers.local

the file that will be included is /etc/sudoers.local.

The file name may also include the %h escape, signifying the short form of the host name. In other words, if the machine's host name is 'xerxes', then

@include /etc/sudoers.%h

will cause sudo to include the file /etc/sudoers.xerxes.

The @includedir directive can be used to create a sudoers.d directory that the system package manager can drop sudoers file rules into as part of package installation. For example, given:

@includedir /etc/sudoers.d

sudo will suspend processing of the current file and read each file in /etc/sudoers.d, skipping file names that end in '~' or contain a '.' character to avoid causing problems with package manager or editor temporary/backup files. Files are parsed in sorted lexical order. That is, /etc/sudoers.d/01_first will be parsed before /etc/sudoers.d/10_second. Be aware that because the sorting is lexical, not numeric, /etc/sudoers.d/1_whoops would be loaded after /etc/sudoers.d/10_second. Using a consistent number of leading zeroes in the file names can be used to avoid such problems. After parsing the files in the directory, control returns to the file that contained the @includedir directive.

Note that unlike files included via @include, visudo will not edit the files in a @includedir directory unless one of them contains a syntax error. It is still possible to run visudo with the -f flag to edit the files directly, but this will not catch the redefinition of an alias that is also present in a different file.

Other special characters and reserved words The pound sign ('#') is used to indicate a comment (unless it is part of a #include directive or 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 user-ID). 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. Attempting to define an alias named ALL will result in a syntax error. Please note that using ALL can be dangerous since in a command context, it allows the user to run any command on the system.

The following option names permitted in an Option_Spec are also considered reserved words: CHROOT, TIMEOUT, CWD, NOTBEFORE and NOTAFTER. Attempting to define an alias with the same name as one of the options will result in a syntax error.

An exclamation point ('!') can be used as a logical not operator in a list or alias as well as in front of a Cmnd. This allows one to exclude certain values. For the '!' operator to be effective, there must be something for it to exclude. For example, to match all users except for root one would use:

ALL,!root

If the ALL, is omitted, as in:

!root

it would explicitly deny root but not match any other users. This is different from a true 'negation' operator.

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.

White space 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 user name or host name): '!', '=', ':', ',', '(', ')', '\'.