package: sudo-logsrvd

title: sudo_logsrv.proto(5)

summary: Sudo log server protocol

text:
# sudo_logsrv.proto(5)

## NAME
sudo_logsrv.proto — Sudo log server protocol

## DESCRIPTION
Starting with version 1.9.0, sudo supports sending event and I/O logs to a log server. The protocol used is written in Google's Protocol Buffers domain specific language. The EXAMPLES section includes a complete description of the protocol in Protocol Buffers format.

Because there is no way to determine message boundaries when using Protocol Buffers, the wire size of each message is sent immediately preceding the message itself as a 32-bit unsigned integer in network byte order. This is referred to as “length-prefix framing” and is how Google suggests handling the lack of message delimiters.

The protocol is made up of two basic messages, ClientMessage and ServerMessage, described below. The server must accept messages up to two megabytes in size. The server may return an error if the client tries to send a message larger than two megabytes.

## Client Messages
A ClientMessage is a container used to encapsulate all the possible message types a client may send to the server.

```
message ClientMessage {
  oneof type {
    AcceptMessage accept_msg = 1;
    RejectMessage reject_msg = 2;
    ExitMessage exit_msg = 3;
    RestartMessage restart_msg = 4;
    AlertMessage alert_msg = 5;
    IoBuffer ttyin_buf = 6;
    IoBuffer ttyout_buf = 7;
    IoBuffer stdin_buf = 8;
    IoBuffer stdout_buf = 9;
    IoBuffer stderr_buf = 10;
    ChangeWindowSize winsize_event = 11;
    CommandSuspend suspend_event = 12;
    ClientHello hello_msg = 13;
  }
}
```

The different ClientMessage sub-messages the client may sent to the server are described below.

### TimeSpec

```
message TimeSpec {
    int64 tv_sec = 1;
    int32 tv_nsec = 2;
}
```

A TimeSpec is the equivalent of a POSIX struct timespec, containing seconds and nanoseconds members. The tv_sec member is a 64-bit integer to support dates after the year 2038.

### InfoMessage

```
message InfoMessage {
  message StringList {
    repeated string strings = 1;
  }
  message NumberList {
    repeated int64 numbers = 1;
  }
  string key = 1;
  oneof value {
    int64 numval = 2;
    string strval = 3;
    StringList strlistval = 4;
    NumberList numlistval = 5;
  }
}
```

An InfoMessage is used to represent information about the invoking user as well as the execution environment the command runs in the form of key-value pairs. The key is always a string but the value may be a 64-bit integer, a string, an array of strings, or an array of 64-bit integers. The event log data is composed of InfoMessage entries. See the EVENT LOG VARIABLES section for more information.

### ClientHello hello_msg

```
message ClientHello {
  string client_id = 1;
}
```

A ClientHello message consists of client information that may be sent to the server when the client first connects.

client_id

A free-form client description. This usually includes the name and version of the client implementation.

### AcceptMessage accept_msg

```
message AcceptMessage {
  TimeSpec submit_time = 1;
  repeated InfoMessage info_msgs = 2;
  bool expect_iobufs = 3;
}
```

An AcceptMessage is sent by the client when a command is allowed by the security policy. It contains the following members:

submit_time

The wall clock time when the command was submitted to the security policy.

info_msgs

An array of InfoMessage describing the user who submitted the command as well as the execution environment of the command. This information is used to generate an event log entry and may also be used by server to determine where and how the I/O log is stored.

expect_iobufs

Set to true if the server should expect IoBuffer messages to follow (for I/O logging) or false if the server should only store the event log.

If an AcceptMessage is sent, the client must not send a RejectMessage or RestartMessage.

### RejectMessage reject_msg

```
message RejectMessage {
  TimeSpec submit_time = 1;
  string reason = 2;
  repeated InfoMessage info_msgs = 3;
}
```

A RejectMessage is sent by the client when a command is denied by the security policy. It contains the following members:

submit_time

The wall clock time when the command was submitted to the security policy.

reason

The reason the security policy gave for denying the command.

info_msgs

An array of InfoMessage describing the user who submitted the command as well as the execution environment of the command. This information is used to generate an event log entry.

If a RejectMessage is sent, the client must not send an AcceptMessage or RestartMessage.

### ExitMessage exit_msg

```
message ExitMessage {
  TimeSpec run_time = 1;
  int32 exit_value = 2;
  bool dumped_core = 3;
  string signal = 4;
  string error = 5;
}
```

An ExitMessage is sent by the client after the command has exited or has been terminated by a signal. It contains the following members:

run_time

The total amount of elapsed time since the command started, calculated using a monotonic clock where possible. This is not the wall clock time.

exit_value

The command's exit value in the range 0–255.

dumped_core

True if the command was terminated by a signal and dumped core.

signal

If the command was terminated by a signal, this is set to the name of the signal without the leading “SIG”. For example, INT, TERM, KILL, SEGV.

error

A message from the client indicating that the command was terminated unexpectedly due to an error.

When performing I/O logging, the client should wait for a commit_point corresponding to the final IoBuffer before closing the connection unless the final commit_point has already been received.

### RestartMessage restart_msg

```
message RestartMessage {
  string log_id = 1;
  TimeSpec resume_point = 2;
}
```

A RestartMessage is sent by the client to resume sending an existing I/O log that was previously interrupted. It contains the following members:

log_id

The server-side name for an I/O log that was previously sent to the client by the server. This may be a path name on the server or some other kind of server-side identifier.

resume_point

The point in time after which to resume the I/O log. This is in the form of a TimeSpec representing the amount of time since the command started, not the wall clock time. The resume_point should correspond to a commit_point previously sent to the client by the server. If the server receives a RestartMessage containing a resume_point it has not previously seen, an error will be returned to the client and the connection will be dropped.

If a RestartMessage is sent, the client must not send an AcceptMessage or RejectMessage.

### AlertMessage alert_msg

```
message AlertMessage {
  TimeSpec alert_time = 1;
  string reason = 2;
  repeated InfoMessage info_msgs = 3;
}
```

An AlertMessage is sent by the client to indicate a problem detected by the security policy while the command is running that should be stored in the event log. It contains the following members:

alert_time

The wall clock time when the alert occurred.

reason

The reason for the alert.

info_msgs

An optional array of InfoMessage describing the user who submitted the command as well as the execution environment of the command. This information is used to generate an event log entry.

### IoBuffer ttyin_buf | ttyout_buf | stdin_buf | stdout_buf | stderr_buf

```
message IoBuffer {
  TimeSpec delay = 1;
  bytes data = 2;
}
```

An IoBuffer is used to represent data from terminal input, terminal output, standard input, standard output, or standard error. It contains the following members:

delay

The elapsed time since the last record in the form of a TimeSpec. The delay should be calculated using a monotonic clock where possible.

data

The binary I/O log data from terminal input, terminal output, standard input, standard output, or standard error.

### ChangeWindowSize winsize_event

```
message ChangeWindowSize {
  TimeSpec delay = 1;
  int32 rows = 2;
  int32 cols = 3;
}
```

A ChangeWindowSize message is sent by the client when the terminal running the command changes size. It contains the following members:

delay

The elapsed time since the last record in the form of a TimeSpec. The delay should be calculated using a monotonic clock where possible.

rows

The new number of terminal rows.

cols

The new number of terminal columns.

### CommandSuspend suspend_event

```
message CommandSuspend {
  TimeSpec delay = 1;
  string signal = 2;
}
```

A CommandSuspend message is sent by the client when the command is either suspended or resumed. It contains the following members:

delay

The elapsed time since the last record in the form of a TimeSpec. The delay should be calculated using a monotonic clock where possible.

signal

The signal name without the leading “SIG”. For example, STOP, TSTP, CONT.

## Server Messages
A ServerMessage is a container used to encapsulate all the possible message types the server may send to a client.

```
message ServerMessage {
  oneof type {
    ServerHello hello = 1;
    TimeSpec commit_point = 2;
    string log_id = 3;
    string error = 4;
    string abort = 5;
  }
}
```

The different ServerMessage sub-messages the server may sent to the client are described below.

### ServerHello hello

```
message ServerHello {
  string server_id = 1;
  string redirect = 2;
  repeated string servers = 3;
  bool subcommands = 4;
}
```

The ServerHello message consists of server information sent when the client first connects. It contains the following members:

server_id

A free-form server description. Usually this includes the name and version of the implementation running on the log server. This member is always present.

redirect

A host and port separated by a colon (‘’): that the client should connect to instead. The host may be a host name, an IPv4 address, or an IPv6 address in square brackets. This may be used for server load balancing. The server will disconnect after sending the ServerHello when it includes a redirect.

servers

A list of other known log servers. This can be used to implement log server redundancy and allows the client to discover all other log servers simply by connecting to one known server. This member may be omitted when there is only a single log server.

subcommands

If set, the server supports logging additional commands during a session. The client may send an AcceptMessage or RejectMessage when sudo is running in intercept mode. In this mode, commands spawned from the initial command authorized by sudo are subject to policy restrictions and/or are logged. If subcommands is false, the client must not attempt to log additional commands.

### TimeSpec commit_point
A periodic time stamp sent by the server to indicate when I/O log buffers have been committed to storage. This message is not sent after every IoBuffer but rather at a server-configurable interval. When the server receives an ExitMessage, it will respond with a commit_point corresponding to the last received IoBuffer before closing the connection.

### string log_id
The server-side ID of the I/O log being stored, sent in response to an AcceptMessage where expect_iobufs is true.

### string error
A fatal server-side error. The server will close the connection after sending the error message.

### string abort
An abort message from the server indicates that the client should kill the command and terminate the session. It may be used to implement simple server-side policy. The server will close the connection after sending the abort message.

## Protocol flow of control
The expected protocol flow is as follows:

- Client connects to the first available server. If the client is configured to use TLS, a TLS handshake will be attempted.

- Client sends ClientHello. This is currently optional but allows the server to detect a non-TLS connection on the TLS port.

- Server sends ServerHello.

- Client responds with either AcceptMessage, RejectMessage, or RestartMessage.

- If client sent a AcceptMessage with expect_iobufs set, server creates a new I/O log and responds with a log_id.

- Client sends zero or more IoBuffer messages.

- Server periodically responds to IoBuffer messages with a commit_point.

- Client sends an ExitMessage when the command exits or is killed.

- Server sends the final commit_point if one is pending.

- Server closes the connection. After receiving the final commit_point, the client shuts down its side of the TLS connection if TLS is in use, and closes the connection.

- Server shuts down its side of the TLS connection if TLS is in use, and closes the connection.

At any point, the server may send an error or abort message to the client at which point the server will close the connection. If an abort message is received, the client should terminate the running command.

## EVENT LOG VARIABLES
AcceptMessage, AlertMessage and RejectMessage classes contain an array of InfoMessage that should contain information about the user who submitted the command as well as information about the execution environment of the command if it was accepted.

Some variables have a client, run, or submit prefix. These prefixes are used to eliminate ambiguity for variables that could apply to the client program, the user submitting the command, or the command being run. Variables with a client prefix pertain to the program performing the connection to the log server, for example sudo. Variables with a run prefix pertain to the command that the user requested be run. Variables with a submit prefix pertain to the user submitting the request (the user running sudo).

The following InfoMessage entries are required:

Key

Type

Description

command

string

command that was submitted

runuser

string

name of user the command was run as

submithost

string

name of host the command was submitted on

submituser

string

name of user submitting the command

The following InfoMessage entries are recognized, but not required:

Key

Type

Description

clientargv

StringList

client's original argument vector

clientpid

int64

client's process ID

clientppid

int64

client's parent process ID

clientsid

int64

client's terminal session ID

columns

int64

number of columns in the terminal

lines

int64

number of lines in the terminal

runargv

StringList

argument vector of command to run

runchroot

string

root directory of command to run

runcwd

string

running command's working directory

runenv

StringList

the running command's environment

rungid

int64

primary group-ID of the command

rungids

NumberList

supplementary group-IDs for the command

rungroup

string

primary group name of the command

rungroups

StringList

supplementary group names for the command

runuid

int64

run user's user-ID

submitcwd

string

submit user's current working directory

submitenv

StringList

the submit user's environment

submitgid

int64

submit user's primary group-ID

submitgids

NumberList

submit user's supplementary group-IDs

submitgroup

string

submitting user's primary group name

submitgroups

StringList

submit user's supplementary group names

submituid

int64

submit user's user-ID

ttyname

string

terminal the command was submitted from

The server must accept other variables not listed above but may ignore them.

## EXAMPLES
The Protocol Buffers description of the log server protocol, using “proto3” syntax, is included in full below.

```
syntax = "proto3";

/*
 * Client message to the server.  Messages on the wire are
 * prefixed with a 32-bit size in network byte order.
 */
message ClientMessage {
  oneof type {
    AcceptMessage accept_msg = 1;
    RejectMessage reject_msg = 2;
    ExitMessage exit_msg = 3;
    RestartMessage restart_msg = 4;
    AlertMessage alert_msg = 5;
    IoBuffer ttyin_buf = 6;
    IoBuffer ttyout_buf = 7;
    IoBuffer stdin_buf = 8;
    IoBuffer stdout_buf = 9;
    IoBuffer stderr_buf = 10;
    ChangeWindowSize winsize_event = 11;
    CommandSuspend suspend_event = 12;
  }
}

/* Equivalent of POSIX struct timespec */
message TimeSpec {
    int64 tv_sec = 1;		/* seconds */
    int32 tv_nsec = 2;		/* nanoseconds */
}

/* I/O buffer with keystroke data */
message IoBuffer {
  TimeSpec delay = 1;		/* elapsed time since last record */
  bytes data = 2;		/* keystroke data */
}

/*
 * Key/value pairs, like Privilege Manager struct info.
 * The value may be a number, a string, or a list of strings.
 */
message InfoMessage {
  message StringList {
    repeated string strings = 1;
  }
  message NumberList {
    repeated int64 numbers = 1;
  }
  string key = 1;
  oneof value {
    int64 numval = 2;
    string strval = 3;
    StringList strlistval = 4;
    NumberList numlistval = 5;
  }
}

/*
 * Event log data for command accepted by the policy.
 */
message AcceptMessage {
  TimeSpec submit_time = 1;		/* when command was submitted */
  repeated InfoMessage info_msgs = 2;	/* key,value event log data */
  bool expect_iobufs = 3;		/* true if I/O logging enabled */
}

/*
 * Event log data for command rejected by the policy.
 */
message RejectMessage {
  TimeSpec submit_time = 1;		/* when command was submitted */
  string reason = 2;			/* reason command was rejected */
  repeated InfoMessage info_msgs = 3;	/* key,value event log data */
}

/* Message sent by client when command exits. */
/* Might revisit runtime and use end_time instead */
message ExitMessage {
  TimeSpec run_time = 1;	/* total elapsed run time */
  int32 exit_value = 2;		/* 0–255 */
  bool dumped_core = 3;		/* true if command dumped core */
  string signal = 4;		/* signal name if killed by signal */
  string error = 5;		/* if killed due to other error */
}

/* Alert message, policy module-specific. */
message AlertMessage {
  TimeSpec alert_time = 1;		/* time alert message occurred */
  string reason = 2;			/* policy alert error string */
  repeated InfoMessage info_msgs = 3;	/* key,value event log data */
}

/* Used to restart an existing I/O log on the server. */
message RestartMessage {
  string log_id = 1;		/* ID of log being restarted */
  TimeSpec resume_point = 2;	/* resume point (elapsed time) */
}

/* Window size change event. */
message ChangeWindowSize {
  TimeSpec delay = 1;		/* elapsed time since last record */
  int32 rows = 2;		/* new number of rows */
  int32 cols = 3;		/* new number of columns */
}

/* Command suspend/resume event. */
message CommandSuspend {
  TimeSpec delay = 1;		/* elapsed time since last record */
  string signal = 2;		/* signal that caused suspend/resume */
}

/*
 * Server messages to the client.  Messages on the wire are
 * prefixed with a 32-bit size in network byte order.
 */
message ServerMessage {
  oneof type {
    ServerHello hello = 1;	/* server hello message */
    TimeSpec commit_point = 2;	/* cumulative time of records stored */
    string log_id = 3;		/* ID of server-side I/O log */
    string error = 4;		/* error message from server */
    string abort = 5;		/* abort message, kill command */
  }
}

/* Hello message from server when client connects. */
message ServerHello {
  string server_id = 1;		/* free-form server description */
  string redirect = 2;		/* optional redirect if busy */
  repeated string servers = 3;	/* optional list of known servers */
}
```

## SEE ALSO
sudo_logsrvd.conf(5), sudoers(5), sudo(8), sudo_logsrvd(8)

Protocol Buffers, https://protobuf.dev/.

## AUTHORS
Many people have worked on sudo over the years; this version consists of code written primarily by:

Todd C. Miller

See the CONTRIBUTORS.md file in the sudo distribution (https://www.sudo.ws/about/contributors/) for an exhaustive list of people who have contributed to sudo.

## BUGS
If you believe you have found a bug in sudo_logsrv.proto, you can either file a bug report in the sudo bug database, https://bugzilla.sudo.ws/, or open an issue at https://github.com/sudo-project/sudo/issues. If you would prefer to use email, messages may be sent to the sudo-workers mailing list, https://www.sudo.ws/mailman/listinfo/sudo-workers (public) or <sudo@sudo.ws> (private).

Please do not report security vulnerabilities through public GitHub issues, Bugzilla or mailing lists. Instead, report them via email to <Todd.Miller@sudo.ws>. You may encrypt your message with PGP if you would like, using the key found at https://www.sudo.ws/dist/PGPKEYS.

## SUPPORT
Limited free support is available via the sudo-users mailing list, see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search the archives.

## DISCLAIMER
sudo 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. See the LICENSE.md file distributed with sudo or https://www.sudo.ws/about/license/ for complete details.


title: sudo_logsrvd.conf(5)

summary: configuration for sudo_logsrvd

text:
# sudo_logsrvd.conf(5)

## NAME
sudo_logsrvd.conf — configuration for sudo_logsrvd

## DESCRIPTION
The sudo_logsrvd.conf file is used to configure the sudo_logsrvd log server. It uses an INI-style format made up of sections in square brackets and “key = value” pairs specific to each section below the section name. Depending on the key, values may be integers, booleans, or strings. Section and key names are not case sensitive, but values are.

The pound sign (‘#’) is used to indicate a comment. Both the comment character and any text after it, up to the end of the line, are ignored. Lines beginning with a semi-colon (‘;’) are also ignored.

Long lines can be continued with a backslash (‘\’) as the last character on the line. Leading white space is removed from the beginning of lines even when the continuation character is used.

The EXAMPLES section contains a copy of the default sudo_logsrvd.conf file.

The following configuration sections are recognized:

- server

- relay

- iolog

- eventlog

- syslog

- logfile

Each section is described in detail below.

### server
The server section configures the address and port the server will listen on. The following keys are recognized:

listen_address = host[:port][(tls)]

The host name or IP address, optional port to listen on and an optional Transport Layer Security (TLS) flag in parentheses. The host may be a host name, an IPv4 address, an IPv6 address in square brackets or the wild card entry ‘*’. A host setting of ‘*’ will cause sudo_logsrvd to listen on all configured network interfaces.

If the optional tls flag is present, sudo_logsrvd will secure the connection with TLS version 1.2 or 1.3. Versions of TLS prior to 1.2 are not supported. See sudo_logsrvd(8) for details on generating TLS keys and certificates.

If a port is specified, it may either be a port number or a known service name as defined by the system service name database. If no port is specified, port 30343 will be used for plaintext connections and port 30344 will be used for TLS connections.

The default value is:

```
listen_address = *:30343
listen_address = *:30344(tls)
```

which will listen on all configured network interfaces for both plaintext and TLS connections. Multiple listen_address lines may be specified to listen on more than one port or interface.

server_log = string

Where to log server warning and error messages. Supported values are none, stderr, syslog, or a path name beginning with the ‘/’ character. A value of stderr is only effective when used in conjunction with the -n option. The default value is syslog.

pid_file = path

The path to the file containing the process ID of the running sudo_logsrvd. If set to an empty value, or if sudo_logsrvd is run with the -n option, no pid_file will be created. If pid_file refers to a symbolic link, it will be ignored. The default value is /run/sudo/sudo_logsrvd.pid.

tcp_keepalive = boolean

If true, sudo_logsrvd will enable the TCP keepalive socket option on the client connection. This enables the periodic transmission of keepalive messages to the client. If the client does not respond to a message in time, the connection will be closed. Defaults to true.

timeout = number

The amount of time, in seconds, sudo_logsrvd will wait for the client to respond. A value of 0 will disable the timeout. The default value is 30.

tls_cacert = path

The path to a certificate authority bundle file, in PEM format, to use instead of the system's default certificate authority database when authenticating clients. The default is to use /etc/ssl/sudo/cacert.pem if it exists, otherwise the system's default certificate authority database is used.

tls_cert = path

The path to the server's certificate file, in PEM format. The default value is /etc/ssl/sudo/certs/logsrvd_cert.pem.

tls_checkpeer = bool

If true, client certificates will be validated by sudo_logsrvd; clients without a valid certificate will be unable to connect. If false, no validation of client certificates will be performed. It true and client certificates are created using a private certificate authority, the tls_cacert setting must be set to a CA bundle that contains the CA certificate used to generate the client certificate. The default value is false.

tls_ciphers_v12 = string

A list of ciphers to use for connections secured by TLS version 1.2 only, separated by a colon ‘:’. See the CIPHER LIST FORMAT section in openssl-ciphers(1) for full details. The default value is “HIGH:!aNULL” which consists of encryption cipher suites with key lengths larger than 128 bits, and some cipher suites with 128-bit keys. Cipher suites that offer no authentication are excluded.

tls_ciphers_v13 = string

A list of ciphers to use for connections secured by TLS version 1.3 only, separated by a colon ‘:’. Supported cipher suites depend on the version of OpenSSL used, but should include the following:

TLS_AES_128_GCM_SHA256

TLS_AES_256_GCM_SHA384

TLS_CHACHA20_POLY1305_SHA256

TLS_AES_128_CCM_SHA256

TLS_AES_128_CCM_8_SHA256

The default cipher suite is “TLS_AES_256_GCM_SHA384”.

tls_dhparams = path

The path to a file containing custom Diffie-Hellman parameters in PEM format. This file can be created with the following command:

```
openssl dhparam -out /etc/sudo_logsrvd_dhparams.pem 2048
```

By default, sudo_logsrvd will use the OpenSSL defaults for Diffie-Hellman key generation.

tls_key = path

The path to the server's private key file, in PEM format. The default value is /etc/ssl/sudo/private/logsrvd_key.pem.

tls_verify = bool

If true, sudo_logsrvd will validate its own certificate at startup time or when the configuration is changed. If false, no verification is performed of the server certificate. When using self-signed certificates without a certificate authority, this setting should be set to false. The default value is true.

### relay
The relay section configures the optional logsrv relay host and port the server will connect to. The TLS configuration keys are optional, by default the corresponding keys in the server section will be used. They are only present in this section to make it possible for the relay connection to use a different set of TLS parameters from the client-facing server. The following keys are recognized:

connect_timeout = number

The amount of time, in seconds, sudo_logsrvd will wait for the connection to a relay_host (see below) to complete. Once the connection is complete, the timeout setting controls the amount of time sudo_logsrvd will wait for the relay to respond. A value of 0 will disable the timeout. The default value is 30.

relay_dir = path

The directory in which log messages are temporarily stored before they are sent to the relay host. Messages are stored in the wire format specified by sudo_logsrv.proto(5) The default value is /var/log/sudo_logsrvd.

relay_host = host[:port][(tls)]

The relay host name or IP address, optional port to connect to and an optional Transport Layer Security (TLS) flag in parentheses. The syntax is identical to listen_address in the server section with one exception: the wild card ‘*’ syntax is not supported. When this setting is enabled, messages from the client will be forwarded to one of the specified relay hosts instead of being stored locally. The host could be running an instance of sudo_logsrvd or another server that supports the sudo_logsrv.proto(5) protocol.

If multiple relay_host lines are specified, the first available relay host will be used.

retry_interval = number

The number of seconds to wait after a connection error before making a new attempt to forward a message to a relay host. The default value is 30.

store_first = boolean

If true, sudo_logsrvd will store logs locally before relaying them. Once the log is complete, a connection to the relay host is opened and the log is relayed. If the network connection is interrupted before the log can be fully transferred, it will be retransmitted later. The default is to relay logs in real-time.

tcp_keepalive = boolean

If true, sudo_logsrvd will enable the TCP keepalive socket option on the relay connection. This enables the periodic transmission of keepalive messages to the relay server. If the relay does not respond to a message in time, the connection will be closed.

timeout = number

The amount of time, in seconds, sudo_logsrvd will wait for the relay server to respond after a connection has succeeded. A value of 0 will disable the timeout. The default value is 30.

tls_cacert = path

The path to a certificate authority bundle file, in PEM format, to use instead of the system's default certificate authority database when authenticating clients. The default is to use the value specified in the server section, or the system's default certificate authority database if no value is set.

tls_cert = path

The path to the server's certificate file, in PEM format. The default is to use the value specified in the server section.

tls_checkpeer = bool

If true, the relay host's certificate will be validated by sudo_logsrvd; connections to a relay without a valid certificate will fail. If false, no validation of relay certificates will be performed. It true and relay certificates are created using a private certificate authority, the tls_cacert setting must be set to a CA bundle that contains the CA certificate used to generate the relay certificate. The default is to use the value specified in the server section.

tls_ciphers_v12 = string

A list of ciphers to use for connections secured by TLS version 1.2 only, separated by a colon ‘:’. See the CIPHER LIST FORMAT section in openssl-ciphers(1) for full details. The default is to use the value specified in the server section.

tls_ciphers_v13 = string

A list of ciphers to use for connections secured by TLS version 1.3 only, separated by a colon ‘:’. Supported cipher suites depend on the version of OpenSSL used, see the server section for more information. The default is to use the value specified in the server section.

tls_dhparams = path

The path to a file containing custom Diffie-Hellman parameters in PEM format. The default is to use the value specified in the server section.

tls_key = path

The path to the server's private key file, in PEM format. The default is to use the value specified in the server section.

tls_verify = bool

If true, the server's certificate used for relaying will be verified at startup. If false, no verification is performed of the server certificate. When using self-signed certificates without a certificate authority, this setting should be set to false. The default is to use the value specified in the server section.

### iolog
The iolog section configures I/O log parameters. These settings are identical to the I/O configuration in sudoers(5). The following keys are recognized:

iolog_compress = boolean

If set, I/O logs will be compressed using zlib. Enabling compression can make it harder to view the logs in real-time as the program is executing due to buffering. The default value is false.

iolog_dir = path

The top-level directory to use when constructing the path name for the I/O log directory. The session sequence number, if any, is stored in the directory. The default value is /var/log/sudo-io. The following percent (‘%’) escape sequences are supported:

%{seq}

expanded to a monotonically increasing base-36 sequence number, such as 0100A5, where every two digits are used to form a new directory, e.g., 01/00/A5

%{user}

expanded to the invoking user's login name

%{group}

expanded to the name of the invoking user's real group-ID

%{runas_user}

expanded to the login name of the user the command will be run as (e.g., root)

%{runas_group}

expanded to the group name of the user the command will be run as (e.g., wheel)

%{hostname}

expanded to the local host name without the domain name

%{command}

expanded to the base name of the command being run

In addition, any escape sequences supported by the system's strftime(3) function will be expanded.

To include a literal ‘%’ character, the string ‘%%’ should be used.

iolog_file = path

The path name, relative to iolog_dir, in which to store I/O logs. It is possible for iolog_file to contain directory components. The default value is “%{seq}”. See the iolog_dir setting above for a list of supported percent (‘%’) escape sequences.

In addition to the escape sequences, path names that end in six or more Xs will have the Xs replaced with a unique combination of digits and letters, similar to the mktemp(3) function.

If the path created by concatenating iolog_dir and iolog_file already exists, the existing I/O log file will be truncated and overwritten unless iolog_file ends in six or more Xs.

iolog_flush = boolean

If set, I/O log data is flushed to disk after each write instead of buffering it. This makes it possible to view the logs in real-time as the program is executing but may significantly reduce the effectiveness of I/O log compression. I/O logs are always flushed before sending a commit point to the client regardless of this setting. The default value is true.

iolog_group = name

The group name to look up when setting the group-ID on new I/O log files and directories. If iolog_group is not set, the primary group-ID of the user specified by iolog_user is used. If neither iolog_group nor iolog_user are set, I/O log files and directories are created with group-ID 0.

iolog_mode = mode

The file mode to use when creating I/O log files. Mode bits for read and write permissions for owner, group, or other are honored, everything else is ignored. The file permissions will always include the owner read and write bits, even if they are not present in the specified mode. When creating I/O log directories, search (execute) bits are added to match the read and write bits specified by iolog_mode. The default value is 0600.

iolog_user = name

The user name to look up when setting the owner of new I/O log files and directories. If iolog_group is set, it will be used instead of the user's primary group-ID. By default, I/O log files and directories are created with user and group-ID 0.

log_passwords = bool

Most programs that require a user's password will disable echo before reading the password to avoid displaying the plaintext password on the screen. However, if terminal input is being logged, the password will still be present in the I/O log. If log_passwords is set to false, sudo_logsrvd will attempt to prevent passwords from being logged. It does this by using the regular expressions in passprompt_regex to match a password prompt in the terminal output buffer. When a match is found, input characters in the I/O log will be replaced with ‘*’ until either a line feed or carriage return is found in the terminal input or a new terminal output buffer is received. If, however, a program displays characters as the user types them (such as sudo when the pwfeedback option is set), only the first character of the password will be replaced in the I/O log. The default value is true.

maxseq = number

The maximum sequence number that will be substituted for the “%{seq}” escape in the I/O log file (see the iolog_dir description above for more information). While the value substituted for “%{seq}” is in base 36, maxseq itself should be expressed in decimal. Values larger than 2176782336 (which corresponds to the base 36 sequence number “ZZZZZZ”) will be silently truncated to 2176782336. The default value is 2176782336.

passprompt_regex = string

One or more POSIX extended regular expressions used to match password prompts in the terminal output when log_passwords is disabled. As an extension, if the regular expression begins with “(?i)”, it will be matched in a case-insensitive manner. Multiple passprompt_regex settings may be specified. Each regular expression is limited to 1024 characters. The default value is “[Pp]assword[: ]*”.

### eventlog
The eventlog section configures how (and if) security policy events are logged.

log_type = string

Where to log accept, reject, and alert events reported by the policy. Supported values are syslog, logfile, and none. The default value is syslog.

log_exit = boolean

If true, sudo_logsrvd will log an event when a command exits or is terminated by a signal. Defaults to false.

log_format = string

The event log format. Supported log formats are: json

Currently, this is an alias for json_pretty. In a future version of sudo_logsrvd, json will be equivalent to json_compact. JSON log entries contain the full contents of the accept, reject, exit and alert messages.

json_compact

Log events in “compact” (minified) JSON format. Each event is written as a separate JSON object on single line without extraneous white space. Due to limitations of the protocol, JSON events sent via syslog may be truncated.

json_pretty

Log events in “pretty” JSON format. When logging to a file, the entire file is treated as a single JSON object consisting of multiple events, each event spanning multiple lines. When logging via syslog, there is no difference between the json_pretty and json_compact formats.

sudo

Log events in traditional sudo-style log format. See the EVENT LOGGING section in sudoers(5) for details.

The default value is sudo.

### syslog
The syslog section configures how events are logged via syslog(3).

facility = string

Syslog facility if syslog is being used for logging. Defaults to authpriv. The following syslog facilities are supported: authpriv (if your OS supports it), auth, daemon, user, local0, local1, local2, local3, local4, local5, local6, and local7.

accept_priority = string

Syslog priority to use when the user is allowed to run a command and authentication is successful. Defaults to notice. The following syslog priorities are supported: alert, crit, debug, emerg, err, info, notice, warning, and none. Setting it to a value of none will disable logging of successful commands.

reject_priority = string

Syslog priority to use when the user is not allowed to run a command or when authentication is unsuccessful. Defaults to alert. See accept_priority for the list of supported syslog priorities.

alert_priority = string

Syslog priority to use for event log alert messages received from the client. Defaults to alert. See accept_priority for the list of supported syslog priorities.

maxlen = number

On many systems, syslog(3) has a relatively small log buffer. IETF RFC 5424 states that syslog servers must support messages of at least 480 bytes and should support messages up to 2048 bytes. By default, sudo_logsrvd creates log messages up to 960 bytes which corresponds to the historic BSD syslog implementation which used a 1024 byte buffer to store the message, date, hostname, and program name. To prevent syslog messages from being truncated, sudo_logsrvd will split up sudo-style log messages that are larger than maxlen bytes. When a message is split, additional parts will include the string “(command continued)” after the user name and before the continued command line arguments. JSON-format log entries are never split and are not affected by maxlen.

server_facility = string

Syslog facility if syslog is being used for server warning messages. See above for a list of supported facilities. Defaults to daemon

### logfile
The logfile section consists of settings related to logging to a plain file (not syslog).

path = string

The path to the file-based event log. This path must be fully-qualified and start with a ‘/’ character. The default value is /var/log/sudo.log.

time_format = string

The string used when formatting the date and time for file-based event logs. Formatting is performed via the system's strftime(3) function so any escape sequences supported by that function will be expanded. The default value is “%h %e %T” which produces dates like “Oct 3 07:15:24” in the ‘C’ locale.

## FILES
/etc/sudo_logsrvd.conf

Sudo log server configuration file

## EXAMPLES

```
#
# sudo logsrv daemon configuration
#

[server]
# The host name or IP address and port to listen on with an optional TLS
# flag.  If no port is specified, port 30343 will be used for plaintext
# connections and port 30344 will be used to TLS connections.
# The following forms are accepted:
#   listen_address = hostname(tls)
#   listen_address = hostname:port(tls)
#   listen_address = IPv4_address(tls)
#   listen_address = IPv4_address:port(tls)
#   listen_address = [IPv6_address](tls)
#   listen_address = [IPv6_address]:port(tls)
#
# The (tls) suffix should be omitted for plaintext connections.
#
# Multiple listen_address settings may be specified.
# The default is to listen on all addresses.
#listen_address = *:30343
#listen_address = *:30344(tls)

# The file containing the ID of the running sudo_logsrvd process.
#pid_file = /run/sudo/sudo_logsrvd.pid

# Where to log server warnings: none, stderr, syslog, or a path name.
#server_log = syslog

# If true, enable the SO_KEEPALIVE socket option on client connections.
# Defaults to true.
#tcp_keepalive = true

# The amount of time, in seconds, the server will wait for the client to
# respond.  A value of 0 will disable the timeout.  The default value is 30.
#timeout = 30

# If true, the server will validate its own certificate at startup.
# Defaults to true.
#tls_verify = true

# If true, client certificates will be validated by the server;
# clients without a valid certificate will be unable to connect.
# By default, client certs are not checked.
#tls_checkpeer = false

# Path to a certificate authority bundle file in PEM format to use
# instead of the system's default certificate authority database.
#tls_cacert = /etc/ssl/sudo/cacert.pem

# Path to the server's certificate file in PEM format.
# Required for TLS connections.
#tls_cert = /etc/ssl/sudo/certs/logsrvd_cert.pem

# Path to the server's private key file in PEM format.
# Required for TLS connections.
#tls_key = /etc/ssl/sudo/private/logsrvd_key.pem

# TLS cipher list (see "CIPHER LIST FORMAT" in the openssl-ciphers manual).
# This setting is only effective if the negotiated protocol is TLS version
# 1.2.  The default cipher list is HIGH:!aNULL.
#tls_ciphers_v12 = HIGH:!aNULL

# TLS cipher list if the negotiated protocol is TLS version 1.3.
# The default cipher list is TLS_AES_256_GCM_SHA384.
#tls_ciphers_v13 = TLS_AES_256_GCM_SHA384

# Path to the Diffie-Hellman parameter file in PEM format.
# If not set, the server will use the OpenSSL defaults.
#tls_dhparams = /etc/ssl/sudo/logsrvd_dhparams.pem

[relay]
# The host name or IP address and port to send logs to in relay mode.
# The syntax is identical to listen_address with the exception of
# the wild card ('*') syntax.  When this setting is enabled, logs will
# be relayed to the specified host instead of being stored locally.
# This setting is not enabled by default.
#relay_host = relayhost.dom.ain
#relay_host = relayhost.dom.ain(tls)

# The amount of time, in seconds, the server will wait for a connection
# to the relay server to complete.  A value of 0 will disable the timeout.
# The default value is 30.
#connect_timeout = 30

# The directory to store messages in before they are sent to the relay.
# Messages are stored in wire format.
# The default value is /var/log/sudo_logsrvd.
#relay_dir = /var/log/sudo_logsrvd

# The number of seconds to wait after a connection error before
# making a new attempt to forward a message to a relay host.
# The default value is 30.
#retry_interval = 30

# Whether to store the log before relaying it.  If true, enable store
# and forward mode.  If false, the client connection is immediately
# relayed.  Defaults to false.
#store_first = true

# If true, enable the SO_KEEPALIVE socket option on relay connections.
# Defaults to true.
#tcp_keepalive = true

# The amount of time, in seconds, the server will wait for the relay to
# respond.  A value of 0 will disable the timeout.  The default value is 30.
#timeout = 30

# If true, the server's relay certificate will be verified at startup.
# The default is to use the value in the [server] section.
#tls_verify = true

# Whether to verify the relay's certificate for TLS connections.
# The default is to use the value in the [server] section.
#tls_checkpeer = false

# Path to a certificate authority bundle file in PEM format to use
# instead of the system's default certificate authority database.
# The default is to use the value in the [server] section.
#tls_cacert = /etc/ssl/sudo/cacert.pem

# Path to the server's certificate file in PEM format.
# The default is to use the certificate in the [server] section.
#tls_cert = /etc/ssl/sudo/certs/logsrvd_cert.pem

# Path to the server's private key file in PEM format.
# The default is to use the key in the [server] section.
#tls_key = /etc/ssl/sudo/private/logsrvd_key.pem

# TLS cipher list (see "CIPHER LIST FORMAT" in the openssl-ciphers manual).
# this setting is only effective if the negotiated protocol is TLS version
# 1.2.  The default is to use the value in the [server] section.
#tls_ciphers_v12 = HIGH:!aNULL

# TLS cipher list if the negotiated protocol is TLS version 1.3.
# The default is to use the value in the [server] section.
#tls_ciphers_v13 = TLS_AES_256_GCM_SHA384

# Path to the Diffie-Hellman parameter file in PEM format.
# The default is to use the value in the [server] section.
#tls_dhparams = /etc/ssl/sudo/logsrvd_dhparams.pem

[iolog]
# The top-level directory to use when constructing the path name for the
# I/O log directory.  The session sequence number, if any, is stored here.
#iolog_dir = /var/log/sudo-io

# The path name, relative to iolog_dir, in which to store I/O logs.
# It is possible for iolog_file to contain directory components.
#iolog_file = %{seq}

# If set, I/O logs will be compressed using zlib.  Enabling compression can
# make it harder to view the logs in real-time as the program is executing.
#iolog_compress = false

# If set, I/O log data is flushed to disk after each write instead of
# buffering it.  This makes it possible to view the logs in real-time
# as the program is executing but reduces the effectiveness of compression.
#iolog_flush = true

# The group to use when creating new I/O log files and directories.
# If iolog_group is not set, the primary group-ID of the user specified
# by iolog_user is used.  If neither iolog_group nor iolog_user
# are set, I/O log files and directories are created with group-ID 0.
#iolog_group = wheel

# The user to use when setting the user-ID and group-ID of new I/O
# log files and directories.  If iolog_group is set, it will be used
# instead of the user's primary group-ID.  By default, I/O log files
# and directories are created with user and group-ID 0.
#iolog_user = root

# The file mode to use when creating I/O log files.  The file permissions
# will always include the owner read and write bits, even if they are
# not present in the specified mode.  When creating I/O log directories,
# search (execute) bits are added to match the read and write bits
# specified by iolog_mode.
#iolog_mode = 0600

# If disabled, sudo_logsrvd will attempt to avoid logging plaintext
# password in the terminal input using passprompt_regex.
#log_passwords = true

# The maximum sequence number that will be substituted for the "%{seq}"
# escape in the I/O log file.  While the value substituted for "%{seq}"
# is in base 36, maxseq itself should be expressed in decimal.  Values
# larger than 2176782336 (which corresponds to the base 36 sequence
# number "ZZZZZZ") will be silently truncated to 2176782336.
#maxseq = 2176782336

# One or more POSIX extended regular expressions used to match
# password prompts in the terminal output when log_passwords is
# disabled.  Multiple passprompt_regex settings may be specified.
#passprompt_regex = [Pp]assword[: ]*
#passprompt_regex = [Pp]assword for [a-z0-9]+: *

[eventlog]
# Where to log accept, reject, exit, and alert events.
# Accepted values are syslog, logfile, or none.
# Defaults to syslog
#log_type = syslog

# Whether to log an event when a command exits or is terminated by a signal.
# Defaults to false
#log_exit = true

# Event log format.
# Currently only sudo-style event logs are supported.
#log_format = sudo

[syslog]
# The maximum length of a syslog payload.
# On many systems, syslog(3) has a relatively small log buffer.
# IETF RFC 5424 states that syslog servers must support messages
# of at least 480 bytes and should support messages up to 2048 bytes.
# Messages larger than this value will be split into multiple messages.
#maxlen = 960

# The syslog facility to use for event log messages.
# The following syslog facilities are supported: authpriv (if your OS
# supports it), auth, daemon, user, local0, local1, local2, local3,
# local4, local5, local6, and local7.
#facility = authpriv

# Syslog priority to use for event log accept messages, when the command
# is allowed by the security policy.  The following syslog priorities are
# supported: alert, crit, debug, emerg, err, info, notice, warning, none.
#accept_priority = notice

# Syslog priority to use for event log reject messages, when the command
# is not allowed by the security policy.
#reject_priority = alert

# Syslog priority to use for event log alert messages reported by the
# client.
#alert_priority = alert

# The syslog facility to use for server warning messages.
# Defaults to daemon.
#server_facility = daemon

[logfile]
# The path to the file-based event log.
# This path must be fully-qualified and start with a '/' character.
#path = /var/log/sudo.log

# The format string used when formatting the date and time for
# file-based event logs.  Formatting is performed via strftime(3) so
# any format string supported by that function is allowed.
#time_format = %h %e %T
```

## SEE ALSO
strftime(3), sudo.conf(5), sudoers(5), sudo(8), sudo_logsrvd(8)

## AUTHORS
Many people have worked on sudo over the years; this version consists of code written primarily by:

Todd C. Miller

See the CONTRIBUTORS.md file in the sudo distribution (https://www.sudo.ws/about/contributors/) for an exhaustive list of people who have contributed to sudo.

## BUGS
If you believe you have found a bug in sudo_logsrvd.conf, you can either file a bug report in the sudo bug database, https://bugzilla.sudo.ws/, or open an issue at https://github.com/sudo-project/sudo/issues. If you would prefer to use email, messages may be sent to the sudo-workers mailing list, https://www.sudo.ws/mailman/listinfo/sudo-workers (public) or <sudo@sudo.ws> (private).

Please do not report security vulnerabilities through public GitHub issues, Bugzilla or mailing lists. Instead, report them via email to <Todd.Miller@sudo.ws>. You may encrypt your message with PGP if you would like, using the key found at https://www.sudo.ws/dist/PGPKEYS.

## SUPPORT
Limited free support is available via the sudo-users mailing list, see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search the archives.

## DISCLAIMER
sudo 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. See the LICENSE.md file distributed with sudo or https://www.sudo.ws/about/license/ for complete details.


package: sudo-python

title: sudo_plugin_python(5)

summary: Sudo Plugin API (Python)

text:
# sudo_plugin_python(5)

## NAME
sudo_plugin_python — Sudo Plugin API (Python)

## DESCRIPTION
Starting with version 1.9, sudo plugins can be written in python. The API closely follows the C sudo plugin API described by sudo_plugin(5).

The supported plugins types are:

- Policy plugin

- I/O plugin

- Audit plugin

- Approval plugin

- Group provider plugin

Python plugin support needs to be explicitly enabled at build time with the configure option “--enable-python”. Python version 3.0 or higher is required.

### Sudo Python Plugin Base
A plugin written in Python should be a class in a python file that inherits from sudo.Plugin. The sudo.Plugin base class has no real purpose other than to identify this class as a plugin.

The only implemented method is a constructor, which stores the keyword arguments it receives as fields (member variables) in the object. This is intended as a convenience to allow you to avoid writing the constructor yourself.

For example:

```
import sudo

class MySudoPlugin(sudo.Plugin):
    # example constructor (optional)
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    # example destructor (optional)
    def __del__(self):
        pass
```

Both the constructor and destructor are optional and can be omitted.

The customized Plugin class should define a few plugin-specific methods. When the plugin loads, sudo will create an instance of this class and call the methods. The actual methods required depend on the type of the plugin, but most return an int result code, as documented in sudo_plugin(5), that indicates whether or not the method was successful. The Python sudo module defines the following constants to improve readability:

Define

Value

sudo.RC.OK

1

sudo.RC.ACCEPT

1

sudo.RC.REJECT

0

sudo.RC.ERROR

-1

sudo.RC.USAGE_ERROR

-2

If a function returns None (for example, if it does not call return), it will be considered to have returned sudo.RC.OK. If an exception is raised (other than sudo.PluginException), the backtrace will be shown to the user and the plugin function will return sudo.RC.ERROR. If that is not acceptable, you must catch the exception and handle it yourself.

Instead of just returning sudo.RC.ERROR or sudo.RC.REJECT result code the plugin can also provide a message describing the problem. This can be done by raising one of the special exceptions:

```
raise sudo.PluginError("Message")
raise sudo.PluginReject("Message")
```

This added message will be used by the audit plugins. Both exceptions inherit from sudo.PluginException

### Python Plugin Loader
Running the Python interpreter and bridging between C and Python is handled by the sudo plugin python_plugin.so. This shared object can be loaded like any other dynamic sudo plugin and should receive the path and the class name of the Python plugin it is loading as arguments.

Example usage in sudo.conf(5):

```
Plugin python_policy python_plugin.so ModulePath=<path> ClassName=<class>
Plugin python_io python_plugin.so ModulePath=<path> ClassName=<class>
Plugin python_audit python_plugin.so ModulePath=<path> ClassName=<class>
Plugin python_approval python_plugin.so ModulePath=<path> ClassName=<class>
```

Example group provider plugin usage in the sudoers file:

```
Defaults group_plugin="python_plugin.so ModulePath=<path> ClassName=<class>"
```

The plugin arguments are as follows:

ModulePath

The path of a python file which contains the class of the sudo Python plugin. It must be either an absolute path or a path relative to the sudo Python plugin directory, /usr/lib64/sudo/python. The parent directory of ModulePath will be appended to Python's module search path (there is currently no way to force Python to load a module from a fully-qualified path). It is good practice to use a prefix for the module file that is unlikely to conflict with other installed Python modules, for example, sudo_policy.py. Otherwise, if the there is an installed Python module with the same file name as the sudo Python plugin file (without the directory), the wrong file will be loaded.

ClassName

(Optional.) The name of the class implementing the sudo Python plugin. If not supplied, the one and only sudo.Plugin that is present in the module will be used. If there are multiple such plugins in the module (or none), it will result in an error.

### Policy plugin API
Policy plugins must be registered in sudo.conf(5). For example:

```
Plugin python_policy python_plugin.so ModulePath=<path> ClassName=<class>
```

Currently, only a single policy plugin may be specified in sudo.conf(5).

A policy plugin may have the following member functions:

constructor

```
__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...],
    version: str, user_info: Tuple[str, ...],
    plugin_options: Tuple[str, ...])
```

Implementing this function is optional. The default constructor will set the keyword arguments it receives as member variables in the object.

The constructor matches the open() function in the C sudo plugin API.

The function arguments are as follows:

user_env

The user's environment as a tuple of strings in “key=value” format.

settings

A tuple of user-supplied sudo settings in the form of “key=value” strings.

version

The version of the Python Policy Plugin API.

user_info

A tuple of information about the user running the command in the form of “key=value” strings.

plugin_options

The plugin options passed as arguments in the sudo.conf(5) plugin registration. This is a tuple of strings, usually (but not necessarily) in “key=value” format.

The sudo.options_as_dict() convenience function can be used to convert “key=value” pairs to a dictionary. For a list of recognized keys and their supported values, see the policy plugin open() documentation in sudo_plugin(5).

check_policy

```
check_policy(self, argv: Tuple[str, ...], env_add: Tuple[str, ...])
```

The check_policy() function is called by sudo to determine whether the user is allowed to run the specified command. Implementing this function is mandatory for a policy plugin.

The function arguments are as follows:

argv

A tuple describing the command the user wishes to run.

env_add

Additional environment variables specified by the user on the command line in the form of a tuple of “key=value” pairs. The sudo.options_as_dict() convenience function can be used to convert them to a dictionary.

This function should return a result code or a tuple in the following format:

```
return (rc, command_info_out, argv_out, user_env_out)
```

The tuple values are as follows:

rc

The result of the policy check, one of the sudo.RC.* constants. sudo.RC.ACCEPT if the command is allowed, sudo.RC.REJECT if not allowed, sudo.RC.ERROR for a general error, or sudo.RC.USAGE_ERROR for a usage error.

command_info_out

Optional (only required when the command is accepted). Information about the command being run in the form of “key=value” strings. To accept a command, at the very minimum the plugin must set in the command, runas_uid, and runas_gid keys.

For a list of recognized keys and supported values, see the check_policy() documentation in sudo_plugin(5).

argv_out

Optional (only required when the command is accepted). The arguments to pass to the execve(2) system call when executing the command.

user_env_out

Optional (only required when the command is accepted). The environment to use when executing the command in the form of a tuple of strings in “key=value” format.

init_session

```
init_session(self, user_pwd: Tuple, user_env: Tuple[str, ...])
```

Perform session setup (optional). The init_session() function is called before sudo sets up the execution environment for the command before any user-ID or group-ID changes.

The function arguments are as follows:

user_pwd

A tuple describing the user's passwd entry. Convertible to pwd.struct_passwd or None if the user is not present in the password database. Example conversion:

```
user_pwd = pwd.struct_passwd(user_pwd) if user_pwd else None
```

user_env

The environment the command will run in. This is a tuple of strings in “key=value” format.

This function should return a result code or a tuple in the following format:

```
return (rc, user_env_out)
```

The tuple values are as follows:

rc

The result of the session init, one of the sudo.RC.* constants. sudo.RC.OK on success, 0 on failure, or sudo.RC.ERROR if an error occurred.

user_env_out

Optional. If the init_session() function needs to modify the user environment, it can return the new environment in user_env_out. If this is omitted, no changes will be made to user_env.

list

```
list(self, argv: Tuple[str, ...], is_verbose: int, user: str)
```

List available privileges for the invoking user.

The function arguments are as follows:

argv

If not set to None, an argument vector describing a command the user wishes to check against the policy.

is_verbose

Flag indicating whether to list in verbose mode or not.

user

The name of a different user to list privileges for if the policy allows it. If None, the plugin should list the privileges of the invoking user.

validate

```
validate(self)
```

For policy plugins that cache authentication credentials, this function is used to validate and cache the credentials (optional).

invalidate

```
invalidate(self, remove: int)
```

For policy plugins that cache authentication credentials, this function is used to invalidate the credentials (optional).

The function arguments are as follows:

remove

If this flag is set, the plugin may remove the credentials instead of simply invalidating them.

show_version

```
show_version(self, is_verbose: int)
```

Display the plugin version information to the user. The sudo.log_info() function should be used.

The function arguments are as follows:

is_verbose

A flag to indicate displaying more verbose information. Currently this is 1 if ‘sudo -V’ is run as the root user.

close

```
close(self, exit_status: int, error: int)
```

Called when a command finishes executing.

Works the same as the close() function in the C sudo plugin API, except that it only gets called if sudo attempts to execute the command.

The function arguments are as follows:

exit_status

The exit status of the command if was executed, otherwise -1.

error

If the command could not be executed, this is set to the value of errno set by the execve(2) system call, otherwise 0.

### Policy plugin example
Sudo ships with an example Python policy plugin. To try it, register it by adding the following lines to /etc/sudo.conf:

```
Plugin python_policy python_plugin.so \
    ModulePath=/usr/share/doc/sudo-1.9.17p2/examples/example_policy_plugin.py \
    ClassName=SudoPolicyPlugin
```

Only one policy plugin can be enabled at a time so you must disable any other policy plugin listed in /etc/sudo.conf, such as sudoers(5).

### I/O plugin API
I/O plugins must be registered in sudo.conf(5). For example:

```
Plugin python_io python_plugin.so ModulePath=<path> ClassName=<class>
```

Sudo supports loading multiple I/O plugins. Currently only 8 python I/O plugins can be loaded at once.

An I/O plugin may have the following member functions:

constructor

```
__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...],
    version: str, user_info: Tuple[str, ...],
    plugin_options: Tuple[str, ...])
```

Implementing this function is optional. The default constructor will set the keyword arguments it receives as member variables in the object.

The constructor matches the open() function in the C sudo plugin API.

The function arguments are as follows:

user_env

The user's environment as a tuple of strings in “key=value” format.

settings

A tuple of user-supplied sudo settings in the form of “key=value” strings.

version

The version of the Python I/O Plugin API.

user_info

A tuple of information about the user running the command in the form of “key=value” strings.

plugin_options

The plugin options passed as arguments in the sudo.conf(5) plugin registration. This is a tuple of strings, usually (but not necessarily) in “key=value” format.

The sudo.options_as_dict() convenience function can be used to convert “key=value” pairs to a dictionary. For a list of recognized keys and their supported values, see the I/O plugin open() documentation in sudo_plugin(5).

open

```
open(self, argv: Tuple[str, ...],
    command_info: Tuple[str, ...]) -> int
```

Receives the command the user wishes to run.

Works the same as the open() function in the C sudo plugin API except that:

- It only gets called when there is a command to be executed (and not for a version query for example).

- Other arguments of the C API open() function are received through the constructor.

The function arguments are as follows:

argv

A tuple of the arguments describing the command the user wishes to run.

command_info

Information about the command being run in the form of “key=value” strings.

The sudo.options_as_dict() convenience function can be used to convert “key=value” pairs to a dictionary. For a list of recognized keys and their supported values, see the I/O plugin open() documentation in sudo_plugin(5).

The open() function should return a result code, one of the sudo.RC.* constants. If the function returns sudo.RC.REJECT, no I/O will be sent to the plugin.

log_ttyin, log_ttyout, log_stdin, log_stdout, log_stderr

```
log_ttyin(self, buf: str) -> int
log_ttyout(self, buf: str) -> int
log_stdin(self, buf: str) -> int
log_stdout(self, buf: str) -> int
log_stderr(self, buf: str) -> int
```

Receive the user input or output of the terminal device and application standard input, standard output, or standard error. See the matching calls in sudo_plugin(5).

The function arguments are as follows:

buf

The input (or output) buffer in the form of a string.

The function should return a result code, one of the sudo.RC.* constants.

If sudo.RC.ERROR is returned, the running command will be terminated and all of the plugin's logging functions will be disabled. Other I/O logging plugins will still receive any remaining input or output that has not yet been processed.

If an input logging function rejects the data by returning sudo.RC.REJECT, the command will be terminated and the data will not be passed to the command, though it will still be sent to any other I/O logging plugins. If an output logging function rejects the data by returning sudo.RC.REJECT, the command will be terminated and the data will not be written to the terminal, though it will still be sent to any other I/O logging plugins.

change_winsize

```
change_winsize(self, line: int, cols: int) -> int
```

Called whenever the window size of the terminal changes. The function arguments are as follows:

line

The number of lines of the terminal.

cols

The number of columns of the terminal.

log_suspend

```
log_suspend(self, signo: int) -> int
```

Called whenever a command is suspended or resumed. The function arguments are as follows:

signo

The number of the signal that caused the command to be suspended or SIGCONT if the command was resumed.

show_version

```
show_version(self, is_verbose: int)
```

Display the plugin version information to the user. The sudo.log_info() function should be used. The function arguments are as follows:

is_verbose

A flag to indicate displaying more verbose information. Currently this is 1 if ‘sudo -V’ is run as the root user.

close

```
close(self, exit_status: int, error: int) -> None
```

Called when a command finishes execution. Works the same as the close() function in the C sudo plugin API, except that it only gets called if sudo attempts to execute the command.

The function arguments are as follows:

exit_status

The exit status of the command if was executed, otherwise -1.

error

If the command could not be executed, this is set to the value of errno set by the execve(2) system call, otherwise 0.

### I/O plugin example
Sudo ships with a Python I/O plugin example. To try it, register it by adding the following lines to /etc/sudo.conf:

```
Plugin python_io python_plugin.so \
    ModulePath=/usr/share/doc/sudo-1.9.17p2/examples/example_io_plugin.py \
    ClassName=SudoIOPlugin
```

### Audit plugin API
Audit plugins must be registered in sudo.conf(5). For example:

```
Plugin python_audit python_plugin.so ModulePath=<path> ClassName=<class>
```

Sudo supports loading multiple audit plugins. Currently only 8 python audit plugins can be loaded at once.

An audit plugin may have the following member functions (all of which are optional):

constructor

```
__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...],
    version: str, user_info: Tuple[str, ...], plugin_options: Tuple[str, ...])
```

The default constructor will set the keyword arguments it receives as member variables in the object.

The constructor matches the open() function in the C sudo plugin API.

The function arguments are as follows:

user_env

The user's environment as a tuple of strings in “key=value” format.

settings

A tuple of user-supplied sudo settings in the form of “key=value” strings.

version

The version of the Python Audit Plugin API.

user_info

A tuple of information about the user running the command in the form of “key=value” strings.

plugin_options

The plugin options passed as arguments in the sudo.conf(5) plugin registration. This is a tuple of strings, usually (but not necessarily) in “key=value” format.

open

```
open(self, submit_optind: int,
    submit_argv: Tuple[str, ...]) -> int
```

The function arguments are as follows:

submit_optind

The index into submit_argv that corresponds to the first entry that is not a command line option.

submit_argv

The argument vector sudo was invoked with, including all command line options.

close

```
close(self, status_type: int, status: int) -> None
```

Called when sudo is finished, shortly before it exits.

The function arguments are as follows:

status_type

The type of status being passed. One of the sudo.EXIT_REASON.* constants.

status

Depending on the value of status_type, this value is either ignored, the command's exit status as returned by the wait(2) system call, the value of errno set by the execve(2) system call, or the value of errno resulting from an error in the sudo front-end.

show_version

```
show_version(self, is_verbose: int) -> int
```

Display the plugin version information to the user. The sudo.log_info() function should be used.

The function arguments are as follows:

is_verbose

A flag to indicate displaying more verbose information. Currently this is 1 if ‘sudo -V’ is run as the root user.

accept

```
accept(self, plugin_name: str, plugin_type: int, command_info: Tuple[str, ...],
       run_argv: Tuple[str, ...], run_envp: Tuple[str, ...]) -> int
```

This function is called when a command or action is accepted by a policy or approval plugin. The function arguments are as follows:

plugin_name

The name of the plugin that accepted the command or “sudo” for the sudo front-end.

plugin_type

The type of plugin that accepted the command, currently either sudo.PLUGIN_TYPE.POLICY, sudo.PLUGIN_TYPE.APPROVAL, or sudo.PLUGIN_TYPE.SUDO. The accept() function is called multiple times--once for each policy or approval plugin that succeeds and once for the sudo front-end. When called on behalf of the sudo front-end, command_info may include information from an I/O logging plugin as well. Typically, an audit plugin is interested in either the accept status from the sudo front-end or from the various policy and approval plugins, but not both. It is possible for the policy plugin to accept a command that is later rejected by an approval plugin, in which case the audit plugin's accept() and reject() functions will both be called.

command_info

A vector of information describing the command being run. See the sudo_plugin(5) manual for possible values.

run_argv

Argument vector describing a command that will be run.

run_envp

The environment the command will be run with.

reject

```
reject(self, plugin_name: str, plugin_type: int, audit_msg: str,
       command_info: Tuple[str, ...]) -> int
```

This function is called when a command or action is rejected by the policy plugin. The function arguments are as follows:

plugin_name

The name of the plugin that rejected the command.

plugin_type

The type of plugin that rejected the command, currently either sudo.PLUGIN_TYPE.POLICY, sudo.PLUGIN_TYPE.APPROVAL, or sudo.PLUGIN_TYPE.IO. Unlike the accept() function, the reject() function is not called on behalf of the sudo front-end.

audit_msg

An optional string describing the reason the command was rejected by the plugin. If the plugin did not provide a reason, audit_msg will be None.

command_info

A vector of information describing the rejected command. See the sudo_plugin(5) manual for possible values.

error

```
error(self, plugin_name: str, plugin_type: int, audit_msg: str,
      command_info: Tuple[str, ...]) -> int
```

This function is called when a plugin or the sudo front-end returns an error. The function arguments are as follows:

plugin_name

The name of the plugin that generated the error or “sudo” for the sudo front-end.

plugin_type

The type of plugin that generated the error, or SUDO_FRONT_END for the sudo front-end.

audit_msg

An optional string describing the plugin error. If the plugin did not provide a description, it will be None.

command_info

A vector of information describing the command. See the sudo_plugin(5) manual for possible values.

### Audit plugin example
Sudo ships with a Python Audit plugin example. To try it, register it by adding the following lines to /etc/sudo.conf:

```
Plugin python_audit python_plugin.so \
    ModulePath=/usr/share/doc/sudo-1.9.17p2/examples/example_audit_plugin.py \
    ClassName=SudoAuditPlugin
```

It will log the plugin accept / reject / error results to the output.

### Approval plugin API
Approval plugins must be registered in sudo.conf(5). For example:

```
Plugin python_approval python_plugin.so ModulePath=<path> ClassName=<class>
```

Sudo supports loading multiple approval plugins. Currently only 8 python approval plugins can be loaded at once.

An approval plugin may have the following member functions:

constructor

```
__init__(self, user_env: Tuple[str, ...], settings: Tuple[str, ...],
    version: str, user_info: Tuple[str, ...], plugin_options: Tuple[str, ...],
    submit_optind: int, submit_argv: Tuple[str, ...])
```

Optional. The default constructor will set the keyword arguments it receives as member variables in the object.

The constructor matches the open() function in the C sudo plugin API.

The function arguments are as follows:

user_env

The user's environment as a tuple of strings in “key=value” format.

settings

A tuple of user-supplied sudo settings in the form of “key=value” strings.

version

The version of the Python Approval Plugin API.

user_info

A tuple of information about the user running the command in the form of “key=value” strings.

plugin_options

The plugin options passed as arguments in the sudo.conf(5) plugin registration. This is a tuple of strings, usually (but not necessarily) in “key=value” format.

submit_optind

The index into submit_argv that corresponds to the first entry that is not a command line option.

submit_argv

The argument vector sudo was invoked with, including all command line options.

show_version

```
show_version(self, is_verbose: int) -> int
```

Display the version. (Same as for all the other plugins.)

check

```
check(self, command_info: Tuple[str, ...], run_argv: Tuple[str, ...],
      run_env: Tuple[str, ...]) -> int
```

This function is called after policy plugin's check_policy has succeeded. It can reject execution of the command by returning sudo.RC.REJECT or raising the special exception:

```
raise sudo.PluginReject("some message")
```

with the message describing the problem. In the latter case, the audit plugins will get the description.

The function arguments are as follows:

command_info

A vector of information describing the command that will run. See the sudo_plugin(5) manual for possible values.

run_argv

Argument vector describing a command that will be run.

run_env

The environment the command will be run with.

### Approval plugin example
Sudo ships with a Python Approval plugin example. To try it, register it by adding the following lines to /etc/sudo.conf:

```
Plugin python_approval python_plugin.so \
    ModulePath=/usr/share/doc/sudo-1.9.17p2/examples/example_approval_plugin.py \
    ClassName=BusinessHoursApprovalPlugin
```

It will only allow execution of commands in the "business hours" (from Monday to Friday between 8:00 and 17:59:59).

### Sudoers group provider plugin API
A group provider plugin is registered in the sudoers(5) file. For example:

```
Defaults group_plugin="python_plugin.so ModulePath=<path> ClassName=<class>"
```

Currently, only a single group plugin can be registered in sudoers.

A group provider plugin may have the following member functions:

constructor

```
__init__(self, args: Tuple[str, ...], version: str)
```

Implementing this function is optional. The default constructor will set the keyword arguments it receives as member variables in the object.

The function arguments are as follows:

args

The plugin options passed as arguments in the sudoers file plugin registration. All the arguments are free form strings (not necessarily in “key=value” format).

version

The version of the Python Group Plugin API.

query

```
query(self, user: str, group: str, user_pwd: Tuple)
```

The query() function is used to ask the group plugin whether user is a member of group. This method is required.

The function arguments are as follows:

user

The name of the user being looked up in the external group database.

group

The name of the group being queried.

user_pwd

The password database entry for the user, if any. If user is not present in the password database, user_pwd will be NULL.

### Group plugin example
Sudo ships with a Python group plugin example. To try it, register it in the sudoers file by adding the following lines:

```
Defaults group_plugin="python_plugin.so \
    ModulePath=/usr/share/doc/sudo-1.9.17p2/examples/example_group_plugin.py \
    ClassName=SudoGroupPlugin"
```

The example plugin will tell sudo that the user test is part of the non-Unix group mygroup. If you add a rule that uses this group, it will affect the test user. For example:

```
%:mygroup ALL=(ALL) NOPASSWD: ALL
```

Will allow user test to run sudo without a password.

### Hook function API
The hook function API is currently not supported for plugins written in Python.

### Conversation API
A Python plugin can interact with the user using the sudo.conv() function which displays one or more messages described by the sudo.ConvMessage class. This is the Python equivalent of the conversation() function in the C sudo plugin API. A plugin should not attempt to read directly from the standard input or the user's tty (neither of which are guaranteed to exist).

The sudo.ConvMessage class specifies how the user interaction should occur:

```
sudo.ConvMessage(msg_type: int, msg: str, timeout: int)
```

sudo.ConvMessage member variables:

msg_type

Specifies the type of the conversation. See the sudo.CONV.* constants below.

msg

The message to display to the user. The caller must include a trailing newline in msg if one is to be displayed.

timeout

Optional. The maximum amount of time for the conversation in seconds. If the timeout is exceeded, the sudo.conv() function will raise a sudo.ConversationInterrupted exception. The default is to wait forever (no timeout).

To specify the message type, the following constants are available:

- sudo.CONV.PROMPT_ECHO_OFF

- sudo.CONV.PROMPT_ECHO_ON

- sudo.CONV.ERROR_MSG

- sudo.CONV.INFO_MSG

- sudo.CONV.PROMPT_MASK

- sudo.CONV.PROMPT_ECHO_OK

- sudo.CONV.PREFER_TTY

See the sudo_plugin(5) manual for a description of the message types.

The sudo.conv() function performs the actual user interaction:

```
sudo.conv(message(s), on_suspend=suspend_function,
    on_resume=resume_function)
```

The function arguments are as follows:

message(s)

One of more messages (of type sudo.ConvMessage), each describing a conversation. At least one message is required.

on_suspend

An optional callback function which gets called if the conversation is suspended, for example by the user pressing control-Z. The specified function must take a single argument which will be filled with the number of the signal that caused the process to be suspended.

on_resume

An optional callback function which gets called when the previously suspended conversation is resumed. The specified function must take a single argument which will be filled with the number of the signal that caused the process to be suspended.

The sudo.conv() function can raise the following exceptions:

sudo.SudoException

If the conversation fails, for example when the conversation function is not available.

sudo.ConversationInterrupted

If the conversation function returns an error, e.g., the timeout passed or the user interrupted the conversation by pressing control-C.

### Conversation example
Sudo ships with an example plugin demonstrating the Python conversation API. To try it, register it by adding the following lines to /etc/sudo.conf:

```
Plugin python_io python_plugin.so \
    ModulePath=/usr/share/doc/sudo-1.9.17p2/examples/example_conversation.py \
    ClassName=ReasonLoggerIOPlugin
```

### Information / error display API

```
sudo.log_info(string(s), sep=" ", end="\n")
sudo.log_error(string(s), sep=" ", end="\n")
```

To display information to the user, the sudo.log_info() function can be used. To display error messages, use sudo.log_error(). The syntax is similar to the Python print() function.

The function arguments are as follows:

string(s)

One or more strings to display.

sep

An optional string which will be used as the separator between the specified strings. The default is a space character, (‘ ’).

end

An optional string which will be displayed at the end of the message. The default is a new line character (‘\n’).

### Debug API
Debug messages are not visible to the user and are only logged debugging is explicitly enabled in sudo.conf(5). Python plugins can use the sudo.debug() function to make use of sudo's debug system.

Enabling debugging in sudo.conf

To enable debug messages, add a Debug line to sudo.conf(5) with the program set to python_plugin.so. For example, to store debug output in /var/log/sudo_python_debug, use a line like the following:

```
Debug python_plugin.so /var/log/sudo_python_debug \
    plugin@trace,c_calls@trace
```

The debug options are in the form of multiple “subsystem@level” strings, separated by commas (‘,’). For example to just see the debug output of sudo.debug() calls, use:

```
Debug python_plugin.so /var/log/sudo_python_debug plugin@trace
```

See sudo_conf(5) for more details.

The most interesting subsystems for Python plugin development are:

plugin

Logs each sudo.debug() API call.

py_calls

Logs whenever a C function calls into the python module. For example, calling the __init__() function.

c_calls

Logs whenever python calls into a C sudo API function.

internal

Logs internal functions of the python language wrapper plugin.

sudo_cb

Logs when sudo calls into the python plugin API.

load

Logs python plugin loading / unloading events.

You can also specify “all” as the subsystem name to log debug messages for all subsystems.

The sudo.debug() function is defined as:

```
sudo.debug(level, message(s))
```

The function arguments are as follows:

level

an integer, use one of the log level constants below

message(s)

one or more messages to log

Available log levels:

sudo.conf name

Python constant

description

crit

sudo.DEBUG.CRIT

critical errors

err

sudo.DEBUG.ERROR

non-critical errors

warn

sudo.DEBUG.WARN

non-fatal warnings

notice

sudo.DEBUG.NOTICE

non-error condition notices

diag

sudo.DEBUG.DIAG

diagnostic messages

info

sudo.DEBUG.INFO

informational message

trace

sudo.DEBUG.TRACE

log function enter/exit

debug

sudo.DEBUG.DEBUG

very verbose debugging

Using the logging module

Alternatively, a plugin can use the built in logging module of Python as well. Sudo adds its log handler to the root logger, so by default all output of a logger will get forwarded to sudo log system, as it would call sudo.debug.

The log handler of sudo will map each Python log level of a message to the appropriate sudo debug level. The sudo debug system will only receive messages that are not filtered out by the Python loggers. For example, the log level of the python logger will be an additional filter for the log messages, and is usually very different from what level is set in sudo.conf for the sudo debug system.

### Debug example
Sudo ships with an example debug plugin. To try it, register it by adding the following lines to /etc/sudo.conf:

```
Plugin python_io python_plugin.so \
    ModulePath=/usr/share/doc/sudo-1.9.17p2/examples/example_debugging.py \
    ClassName=DebugDemoPlugin

Debug python_plugin.so \
    /var/log/sudo_python_debug plugin@trace,c_calls@trace
```

### Option conversion API
The Python plugin API includes two convenience functions to convert options in “key=value” format to a dictionary and vice versa.

options_as_dict

```
options_as_dict(options)
```

The function arguments are as follows:

options

An iterable (tuple, list, etc.) of strings, each in “key=value” format. This is how the plugin API passes options and settings to a Python plugin.

The function returns the resulting dictionary. Each string of the passed in options will be split at the first equal sign (‘=’) into a key and value. Dictionary keys will never contain this symbol (but values may).

options_from_dict

```
options_from_dict(options_dict)
```

The function arguments are as follows:

options_dict

A dictionary where both the key and the value are strings. The key should not contain an equal sign (‘=’), otherwise the resulting string will have a different meaning. However, this is not currently enforced.

The function returns a tuple containing the strings in “key=value” form for each key and value in the options_dict dictionary passed in. This is how the plugin API accepts options and settings.

## PLUGIN API CHANGELOG (Python)
None yet

## LIMITATIONS
A maximum of 8 python I/O plugins can be loaded at once. If /etc/sudo.conf contains more, those will be rejected with a warning message.

The Event API and the hook function API is currently not accessible for Python plugins.

## SEE ALSO
sudo.conf(5), sudo_plugin(5), sudoers(5), sudo(8)

## AUTHORS
Many people have worked on sudo over the years; this version consists of code written primarily by:

Todd C. Miller

See the CONTRIBUTORS.md file in the sudo distribution (https://www.sudo.ws/about/contributors/) for an exhaustive list of people who have contributed to sudo.

## BUGS
Python plugin support is currently considered experimental.

If you believe you have found a bug in sudo_plugin_python, you can either file a bug report in the sudo bug database, https://bugzilla.sudo.ws/, or open an issue at https://github.com/sudo-project/sudo/issues. If you would prefer to use email, messages may be sent to the sudo-workers mailing list, https://www.sudo.ws/mailman/listinfo/sudo-workers (public) or <sudo@sudo.ws> (private).

Please do not report security vulnerabilities through public GitHub issues, Bugzilla or mailing lists. Instead, report them via email to <Todd.Miller@sudo.ws>. You may encrypt your message with PGP if you would like, using the key found at https://www.sudo.ws/dist/PGPKEYS.

## SECURITY CONSIDERATIONS
All Python plugin handling is implemented inside the python_plugin.so dynamic plugin. Therefore, if no Python plugin is registered in sudo.conf(5) or the sudoers file, sudo will not load the Python interpreter or the Python libraries.

As sudo runs plugins as root, care must be taken when writing Python plugins to avoid creating security vulnerabilities, just as one would when writing plugins in C.

## SUPPORT
Limited free support is available via the sudo-users mailing list, see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or search the archives.

## DISCLAIMER
sudo 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. See the LICENSE.md file distributed with sudo or https://www.sudo.ws/about/license/ for complete details.


title: ibm_hosts(5)

summary: host database for x3270 and c3270

text:
# ibm_hosts(5)

## NAME
ibm_hosts - host database for x3270 and c3270

## SYNOPSIS
/usr/lib/X11/x3270/ibm_hosts

## DESCRIPTION
The ibm_hosts file contains information regarding IBM hosts on the network. An IBM host is a host which can communicate with a 3270 terminal emulator such as x3270 or c3270. Each line defines a name in the following format (optional fields are shown in brackets):

name type [opt:]...[luname@]hostname[:port] [actions]

Items are separated by any number of blanks and/or TAB characters. A line beginning with # is taken as a comment (note that # anywhere else on a line does not indicate a comment).

The name field is a mnemonic used to identify the host.

The type field is a keyword that indicates the type of entry. The value primary means that the name will be included in host-selection menus that may be displayed by a 3270 emulator. The value alias means that the name will not be included in menus, but will still be accepted as valid input when a host name is required.

The hostname field is the Internet hostname or dot-notation Internet address of the host.

The hostname can include `s:' or `p:' prefixes, e.g., s:finicky (see the x3270(1) or c3270(1) man page sfor details). It can also include an LU name, separated by an `@' character, e.g., oddlu@bluehost. Finally, it can include a non-default port number, appended to the hostname with a colon `:' character, e.g., bluehost:97. (For compatability with earlier versions of x3270, the port can also be separated by a slash `/' character.)

The optional actions field specifies actions to be taken once the connection is made and a data-entry field is defined. If the text looks like an action, e.g., PF(1), it is unmodified; otherwise it is taken as the parameter to the String() action. The actions are not intended for entering usernames and passwords; rather they provide an automated way of specifying a front-end menu option.

## EXAMPLE
Given the following ibm_hosts file:

mvs primary mvs-host

tso alias mvs-host

mvs2 primary mvs-host:4012

vm primary vtam Tab() String(3) Enter()

A 3270 emulator will display four names (mvs, mvs2, afhost and vm) on its hosts menu. The names mvs and tso will cause connections to the host mvs-host. The name mvs2 will also cause a connection to mvs-host, but to port 4012 rather than the emulator's default port (usually 23). The name vm will cause the 3270 emulator to connect to the host vtam (presumably some sort of host-selection front-end), enter the string `3' on the second data-entry field on the screen, and send the Enter AID sequence.

## FILES
/usr/lib/X11/x3270/ibm_hosts

## SEE ALSO
x3270(1), c3270(1)


suspend.conf

package: suspend-utils

title: suspend.conf(5)

summary: Config file for the s2disk program

text:
# suspend.conf(5)

## NAME
suspend.conf - Config file for the s2disk program

## DESCRIPTION
This manual page documents briefly the suspend.conf file used by the s2disk, s2both and resume commands.

s2disk is a program that will save the the state of the whole system to disk and power off your system. After restarting your system it will be put back in the exact system state you left it (this is sometimes called hibernation).

## S2RAM / S2BOTH OPTIONS
s2ram_force

If the "s2ram_force" parameter is set to 'y', the s2ram tool will force the suspend process, even the machine is not known, parameters (quirks) are not set nor KMS is not supported.

s2ram_quirks

Specifies the options (quirks) to suspend the machine. Possible options are vbe_post, vbe_save, vbe_mode, radeon_off, pci_save, s3_bios, s3_mode and fb_nosuspend. More information about these options are included in s2ram(8) manpage and the README.s2ram-whitelist file.

## S2DISK / S2BOTH OPTIONS
snapshot device [=/dev/snapshot]

Device via which s2disk should talk to the kernel.

resume device

Specifies the device to write the image to. This is a swap partition or the partition that contains the swap file (see next parameter).

resume offset

Necessary if a swap file is used for suspending. In such a case the device identified by the "resume device" parameter is regarded as the partition that contains the swap file, and "resume offset" must be equal to the offset from the beginning of this partition at which the swap file's header is located, in <PAGE_SIZE> units. The value of this parameter for given swap file can be determined by the swap-offset program (has to be run as root) included in this package. [For this feature to work, you will need an \-mm kernel, 2.6.18-mm3 or newer.]

image size

Limit the size of the system snapshot image created by the s2disk tool, but it's not mandatory. Namely, the s2disk tool will do its best to limit the image size as required by this parameter, but if that's not possible, it will suspend the system anyway, with a bigger image. If "image size" is set to 0, the snapshot image will be as small as possible.

suspend loglevel

You can specify the kernel console loglevel which the s2disk/s2both and resume utilities will use to report progress. On a stock kernel messages with level higher then 7 are usually not shown.

shutdown method

This parameter defines the operation that will be carried out after the suspend image has been created and the machine is ready to be powered off. If it is set to "reboot", the machine will be rebooted immediately. If it is set to "platform", the machine will be shut down using special power management operations available from the kernel that may be necessary for the hardware to be properly reinitialized after the resume, and may cause the system to resume faster (this is the recommended shutdown method on the majority of systems and hence the defaul). If set to "shutdown" the machine will be powered off.

compute checksum

If the "compute checksum" parameter is set to 'y', the s2disk and resume tools will use the MD5 algorithm to verify the image integrity.

compress

If the "compress" parameter is set to 'y', the s2disk and resume tools will use the LZF compression algorithm to compress/decompress the image.

encrypt

If the "encrypt" parameter is set to 'y', the s2disk and resume tools will use the Blowfish encryption algorithm to encrypt/decrypt the image. On resume and suspend you will have to supply a passphrase. By using a pregenerated RSA key, you can avoid having to type a passphrase on suspend. See the "RSA key file" option for more information.

RSA key file

If this option points to a valid RSA key, which can be created with suspend-keygen, the s2disk tool will generate a random key for the Blowfish encryption that will be passed to the resume tool within the image header with the help of the RSA cipher. Consequently you only need to type a passphrase on resume.

early writeout

If the "early writeout" parameter is set to 'y', the s2disk utility will start syncing the resume device early in the process of writing the image to it. [This has been reported to speed up the s2disk on some boxes and eliminates the "fast progress meter and long fsync wait" effect.]

splash

The "splash" parameter is used to make s2disk and/or resume use a splash system (when set to 'y'). Currently the bootsplash.org and splashy systems are supported. For the former you need a kernel patch, the latter is a userspace solution, but you'll need to install a splashy theme. If you use initramfs-tools on your favorite Linux distribution to generate your initramfs, usually the necessary files will be copied to it.

## SEE ALSO
s2disk (8). suspend-keygen(8)

For more information see the README file.

## AUTHOR
This manual page was written by Tim Dijkstra <tim@famdijkstra>.org for the Debian(TM) system (but may be used by others). Was updated by Rodolfo García <kix@kix.es>. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU General Public License, Version 2 any later version published by the Free Software Foundation.

## COPYRIGHT
Copyright © 2006 Tim Dijkstra Copyright © 2012 Rodolfo García (kix)