2 .\" Copyright (c) 2009-2018 Todd C. Miller <Todd.Miller@sudo.ws>
4 .\" Permission to use, copy, modify, and distribute this software for any
5 .\" purpose with or without fee is hereby granted, provided that the above
6 .\" copyright notice and this permission notice appear in all copies.
8 .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 .Dt SUDO_PLUGIN @mansectform@
18 .Os Sudo @PACKAGE_VERSION@
23 Starting with version 1.8,
26 for policy and session logging.
27 Plugins may be compiled as dynamic shared objects (the default on
28 systems that support them) or compiled statically into the
33 policy plugin and an associated I/O logging plugin are used.
36 can be configured to use alternate policy and/or I/O logging plugins
37 provided by third parties.
38 The plugins to be used are specified in the
39 .Xr sudo.conf @mansectform@
42 The API is versioned with a major and minor number.
43 The minor version number is incremented when additions are made.
44 The major number is incremented when incompatible changes are made.
45 A plugin should be check the version passed to it and make sure that the
46 major version matches.
48 The plugin API is defined by the
52 A policy plugin must declare and populate a
54 struct in the global scope.
55 This structure contains pointers to the functions that implement the
58 The name of the symbol should be specified in
59 .Xr sudo.conf @mansectform@
60 along with a path to the plugin so that
64 struct policy_plugin {
65 #define SUDO_POLICY_PLUGIN 1
66 unsigned int type; /* always SUDO_POLICY_PLUGIN */
67 unsigned int version; /* always SUDO_API_VERSION */
68 int (*open)(unsigned int version, sudo_conv_t conversation,
69 sudo_printf_t plugin_printf, char * const settings[],
70 char * const user_info[], char * const user_env[],
71 char * const plugin_options[]);
72 void (*close)(int exit_status, int error);
73 int (*show_version)(int verbose);
74 int (*check_policy)(int argc, char * const argv[],
75 char *env_add[], char **command_info[],
76 char **argv_out[], char **user_env_out[]);
77 int (*list)(int argc, char * const argv[], int verbose,
78 const char *list_user);
79 int (*validate)(void);
80 void (*invalidate)(int remove);
81 int (*init_session)(struct passwd *pwd, char **user_env[]);
82 void (*register_hooks)(int version,
83 int (*register_hook)(struct sudo_hook *hook));
84 void (*deregister_hooks)(int version,
85 int (*deregister_hook)(struct sudo_hook *hook));
89 The policy_plugin struct has the following fields:
94 field should always be set to SUDO_POLICY_PLUGIN.
98 field should be set to
99 .Dv SUDO_API_VERSION .
103 to determine the API version the plugin was
106 .Bd -literal -compact
107 int (*open)(unsigned int version, sudo_conv_t conversation,
108 sudo_printf_t plugin_printf, char * const settings[],
109 char * const user_info[], char * const user_env[],
110 char * const plugin_options[]);
113 Returns 1 on success, 0 on failure, \-1 if a general error occurred,
114 or \-2 if there was a usage error.
117 will print a usage message before it exits.
118 If an error occurs, the plugin may optionally call the
123 .Dv SUDO_CONF_ERROR_MSG
124 to present additional error information to the user.
126 The function arguments are as follows:
129 The version passed in by
131 allows the plugin to determine the
132 major and minor version number of the plugin API supported by
137 function that can be used by the plugin to interact with the user (see below).
138 Returns 0 on success and \-1 on failure.
142 function that may be used to display informational or error messages
144 Returns the number of characters printed on success and \-1 on failure.
146 A vector of user-supplied
148 settings in the form of
151 The vector is terminated by a
154 These settings correspond to flags the user specified when running
156 As such, they will only be present when the corresponding flag has
157 been specified on the command line.
161 the plugin should split on the
167 field will never include one
172 .It bsdauth_type=string
173 Authentication type, if specified by the
178 authentication is supported.
180 If specified, the user has requested via the
184 close all files descriptors with a value of
187 The plugin may optionally pass this, or another value, back in the
190 .It debug_flags=string
191 A debug file path name followed by a space and a comma-separated
192 list of debug flags that correspond to the plugin's
195 .Xr sudo.conf @mansectform@ ,
197 The flags are passed to the plugin exactly as they appear in
198 .Xr sudo.conf @mansectform@ .
204 .Em subsystem Ns @ Ns Em priority
205 but a plugin is free to use a different
206 format so long as it does not include a comma
210 1.8.12, there was no way to specify plugin-specific
212 so the value was always the same as that used by the
214 front end and did not include a path name, only the flags themselves.
215 As of version 1.7 of the plugin interface,
220 .Xr sudo.conf @mansectform@
221 contains a plugin-specific
224 .It debug_level=number
225 This setting has been deprecated in favor of
227 .It ignore_ticket=bool
228 Set to true if the user specified the
231 command, indicating that the user wishes to ignore any cached
232 authentication credentials.
238 to be used similarly to
240 If the plugin does not to support this usage, it may return a value of \-2
243 function, which will cause
245 to print a usage message and
247 .It implied_shell=bool
248 If the user does not specify a program on the command line,
250 will pass the plugin the path to the user's shell and set
251 .It login_class=string
253 login class to use when setting resource limits and nice value,
258 Set to true if the user specified the
260 flag, indicating that
261 the user wishes to run a login shell.
263 The maximum number of groups a user may belong to.
264 This will only be present if there is a corresponding setting in
265 .Xr sudo.conf @mansectform@ .
266 .It network_addrs=list
267 A space-separated list of IP network addresses and netmasks in the
271 .Dq 192.168.1.2/255.255.255.0 .
272 The address and netmask pairs may be either IPv4 or IPv6, depending on
273 what the operating system supports.
274 If the address contains a colon
276 it is an IPv6 address, else it is IPv4.
277 .It noninteractive=bool
278 Set to true if the user specified the
280 flag, indicating that
282 should operate in non-interactive mode.
283 The plugin may reject a command run in non-interactive mode if user
284 interaction is required.
285 .It plugin_dir=string
286 The default plugin directory used by the
289 This is the default directory set at compile time and may not
290 correspond to the directory the running plugin was loaded from.
291 It may be used by a plugin to locate support files.
292 .It plugin_path=string
293 The path name of plugin loaded by the
296 The path name will be a fully-qualified unless the plugin was
297 statically compiled into
299 .It preserve_environment=bool
300 Set to true if the user specified the
302 flag, indicating that
303 the user wishes to preserve the environment.
304 .It preserve_groups=bool
305 Set to true if the user specified the
307 flag, indicating that
308 the user wishes to preserve the group vector instead of setting it
309 based on the runas user.
311 The command name that sudo was run as, typically
316 The prompt to use when requesting a password, if specified via
320 .It remote_host=string
321 The name of the remote host to run the command on, if specified via
325 Support for running the command on a remote host is meant to be implemented
326 via a helper program that is executed in place of the user-specified command.
329 front end is only capable of executing commands on the local host.
330 Only available starting with API version 1.4.
332 Set to true if the user specified the
334 flag, indicating that the user wishes to run a shell.
335 .It runas_group=string
336 The group name or gid to run the command as, if specified via
340 .It runas_user=string
341 The user name or uid to run the command as, if specified via the
344 .It selinux_role=string
345 SELinux role to use when executing the command, if specified by
349 .It selinux_type=string
350 SELinux type to use when executing the command, if specified by
355 Set to true if the user specified the
360 environment variable to the target user's home directory.
364 flag is specified or if invoked as
366 The plugin shall substitute an editor into
370 function or return \-2 with a usage error
371 if the plugin does not support
373 For more information, see the
377 User-specified command timeout.
378 Not all plugins support command timeouts and the ability for the
379 user to set a timeout may be restricted by policy.
380 The format of the timeout string is plugin-specific.
383 Additional settings may be added in the future so the plugin should
384 silently ignore settings that it does not recognize.
386 A vector of information about the user running the command in the form of
389 The vector is terminated by a
395 the plugin should split on the
401 field will never include one
407 The number of columns the user's terminal supports.
408 If there is no terminal device available, a default value of 80 is used.
410 The user's current working directory.
412 The effective group ID of the user invoking
415 The effective user ID of the user invoking
418 The real group ID of the user invoking
421 The user's supplementary group list formatted as a string of
422 comma-separated group IDs.
424 The local machine's hostname as returned by the
428 The number of lines the user's terminal supports.
430 no terminal device available, a default value of 24 is used.
432 The ID of the process group that the running
434 process is a member of.
435 Only available starting with API version 1.2.
437 The process ID of the running
440 Only available starting with API version 1.2.
442 Any (non-comment) strings immediately after the plugin path are
443 passed as arguments to the plugin.
444 These arguments are split on a white space boundary and are passed to
445 the plugin in the form of a
446 .Dv NULL Ns -terminated
457 parameter is only available starting with
461 check the API version specified
464 front end before using
466 Failure to do so may result in a crash.
468 The parent process ID of the running
471 Only available starting with API version 1.2.
473 The session ID of the running
477 is not part of a POSIX job control session.
478 Only available starting with API version 1.2.
480 The ID of the foreground process group associated with the terminal
481 device associated with the
483 process or \-1 if there is no
485 Only available starting with API version 1.2.
487 The path to the user's terminal device.
488 If the user has no terminal device associated with the session,
489 the value will be empty, as in
492 The real user ID of the user invoking
495 The invoking user's file creation mask.
496 Only available starting with API version 1.10.
498 The name of the user invoking
502 The user's environment in the form of a
503 .Dv NULL Ns -terminated vector of
509 the plugin should split on the
515 field will never include one
521 .Bd -literal -compact
522 void (*close)(int exit_status, int error);
527 function is called when the command being run by
531 The function arguments are as follows:
534 The command's exit status, as returned by the
543 If the command could not be executed, this is set to the value of
548 The plugin is responsible for displaying error information via the
553 If the command was successfully executed, the value of
560 function is defined, no I/O logging plugins are loaded,
565 options are set in the
569 front end may execute the command directly instead of running
570 it as a child process.
572 .Bd -literal -compact
573 int (*show_version)(int verbose);
578 function is called by
580 when the user specifies
584 The plugin may display its version information to the user via the
589 .Dv SUDO_CONV_INFO_MSG .
590 If the user requests detailed version information, the verbose flag will be set.
592 Returns 1 on success, 0 on failure, \-1 if a general error occurred,
593 or \-2 if there was a usage error, although the return value is currently
596 .Bd -literal -compact
597 int (*check_policy)(int argc, char * const argv[],
598 char *env_add[], char **command_info[],
599 char **argv_out[], char **user_env_out[]);
604 function is called by
607 whether the user is allowed to run the specified commands.
611 option was enabled in the
616 function, the user has requested
620 is a mechanism for editing one or more files
621 where an editor is run with the user's credentials instead of with
624 achieves this by creating user-writable
625 temporary copies of the files to be edited and then overwriting the
626 originals with the temporary copies after editing is complete.
627 If the plugin supports
629 it should choose the editor to be used, potentially from a variable
630 in the user's environment, such as
634 (note that environment
635 variables may include command line flags).
636 The files to be edited should be copied from
641 editor and its arguments by a
649 before the editor is executed.
650 The plugin should also set
658 function returns 1 if the command is allowed,
659 0 if not allowed, \-1 for a general error, or \-2 for a usage error
662 was specified but is unsupported by the plugin.
665 will print a usage message before it
667 If an error occurs, the plugin may optionally call the
672 .Dv SUDO_CONF_ERROR_MSG
673 to present additional error information to the user.
675 The function arguments are as follows:
678 The number of elements in
680 not counting the final
684 The argument vector describing the command the user wishes to run,
685 in the same form as what would be passed to the
688 The vector is terminated by a
692 Additional environment variables specified by the user on the command
693 line in the form of a
694 .Dv NULL Ns -terminated
698 The plugin may reject the command if one or more variables
699 are not allowed to be set, or it may silently ignore such variables.
703 the plugin should split on the
709 field will never include one
714 Information about the command being run in the form of
717 These values are used by
720 environment when running a command.
721 The plugin is responsible for creating and populating the vector,
722 which must be terminated with a
725 The following values are recognized by
729 The root directory to use when running the command.
733 will close all files descriptors with a value
738 Fully qualified path to the command to be executed.
740 The current working directory to change to when executing the command.
741 .It exec_background=bool
744 runs a command as the foreground process as long as
746 itself is running in the foreground.
749 is enabled and the command is being run in a pty (due to I/O logging
752 setting), the command will be run as a background process.
753 Attempts to read from the controlling terminal (or to change terminal
754 settings) will result in the command being suspended with the
758 in the case of terminal settings).
761 is a foreground process, the command will be granted the controlling terminal
762 and resumed in the foreground with no user intervention required.
763 The advantage of initially running the command in the background is that
765 need not read from the terminal unless the command explicitly requests it.
766 Otherwise, any terminal input must be passed to the command, whether it
767 has required it or not (the kernel buffers terminals so it is not possible
768 to tell whether the command really wants the input).
769 This is different from historic
771 behavior or when the command is not being run in a pty.
773 For this to work seamlessly, the operating system must support the
774 automatic restarting of system calls.
775 Unfortunately, not all operating systems do this by default,
776 and even those that do may have bugs.
777 For example, macOS fails to restart the
781 system calls (this is a bug in macOS).
782 Furthermore, because this behavior depends on the command stopping with the
786 signals, programs that catch these signals and suspend themselves
787 with a different signal (usually
789 will not be automatically foregrounded.
790 Some versions of the linux
792 command behave this way.
793 Because of this, a plugin should not set
795 unless it is explicitly enabled by the administrator and there should
796 be a way to enabled or disable it on a per-command basis.
798 This setting has no effect unless I/O logging is enabled or
806 system call to execute the command instead of
810 must refer to an open file descriptor.
811 .It iolog_compress=bool
812 Set to true if the I/O logging plugins, if any, should compress the
814 This is a hint to the I/O logging plugin which may choose to ignore it.
815 .It iolog_group=string
816 The group that will own newly created I/O log files and directories.
817 This is a hint to the I/O logging plugin which may choose to ignore it.
819 The file permission mode to use when creating I/O log files and directories.
820 This is a hint to the I/O logging plugin which may choose to ignore it.
821 .It iolog_user=string
822 The user that will own newly created I/O log files and directories.
823 This is a hint to the I/O logging plugin which may choose to ignore it.
824 .It iolog_path=string
825 Fully qualified path to the file or directory in which I/O log is
827 This is a hint to the I/O logging plugin which may choose to ignore it.
828 If no I/O logging plugin is loaded, this setting has no effect.
830 Set to true if the I/O logging plugins, if any, should log the
831 standard input if it is not connected to a terminal device.
832 This is a hint to the I/O logging plugin which may choose to ignore it.
833 .It iolog_stdout=bool
834 Set to true if the I/O logging plugins, if any, should log the
835 standard output if it is not connected to a terminal device.
836 This is a hint to the I/O logging plugin which may choose to ignore it.
837 .It iolog_stderr=bool
838 Set to true if the I/O logging plugins, if any, should log the
839 standard error if it is not connected to a terminal device.
840 This is a hint to the I/O logging plugin which may choose to ignore it.
842 Set to true if the I/O logging plugins, if any, should log all
844 This only includes input typed by the user and not from a pipe or
845 redirected from a file.
846 This is a hint to the I/O logging plugin which may choose to ignore it.
847 .It iolog_ttyout=bool
848 Set to true if the I/O logging plugins, if any, should log all
850 This only includes output to the screen, not output to a pipe or file.
851 This is a hint to the I/O logging plugin which may choose to ignore it.
852 .It login_class=string
854 login class to use when setting resource limits and nice value (optional).
855 This option is only set on systems that support login classes.
857 Nice value (priority) to use when executing the command.
858 The nice value, if specified, overrides the priority associated with the
864 If set, prevent the command from executing other programs.
865 .It preserve_fds=list
866 A comma-separated list of file descriptors that should be
867 preserved, regardless of the value of the
870 Only available starting with API version 1.5.
871 .It preserve_groups=bool
874 will preserve the user's group vector instead of
875 initializing the group vector based on
878 Effective group ID to run the command as.
879 If not specified, the value of
883 Effective user ID to run the command as.
884 If not specified, the value of
888 Group ID to run the command as.
889 .It runas_groups=list
890 The supplementary group vector to use for the command in the form
891 of a comma-separated list of group IDs.
894 is set, this option is ignored.
896 User ID to run the command as.
897 .It selinux_role=string
898 SELinux role to use when executing the command.
899 .It selinux_type=string
900 SELinux type to use when executing the command.
902 Create a utmp (or utmpx) entry when a pseudo-tty is allocated.
903 By default, the new entry will be a copy of the user's existing utmp
904 entry (if any), with the tty, time, type and pid fields updated.
909 The plugin may enable
915 This allows the plugin to perform command substitution and transparently
918 when the user attempts to run an editor.
919 .It sudoedit_checkdir=bool
920 Set to false to disable directory writability checks in
924 1.8.16 and higher will check all directory components of the path to be
925 edited for writability by the invoking user.
926 Symbolic links will not be followed in writable directories and
928 will refuse to edit a file located in a writable directory.
929 These restrictions are not enforced when
934 option can be set to false to disable this check.
935 Only available starting with API version 1.8.
936 .It sudoedit_follow=bool
939 to edit files that are symbolic links.
942 1.8.15 and higher will refuse to open a symbolic link.
945 option can be used to restore the older behavior and allow
947 to open symbolic links.
948 Only available starting with API version 1.8.
951 If non-zero then when the timeout expires the command will be killed.
953 The file creation mask to use when executing the command.
955 Allocate a pseudo-tty to run the command in, regardless of whether
956 or not I/O logging is in use.
960 the command in a pty when an I/O log plugin is loaded.
962 User name to use when constructing a new utmp (or utmpx) entry when
965 This option can be used to set the user field in the utmp entry to
966 the user the command runs as rather than the invoking user.
969 will base the new entry on
970 the invoking user's existing entry.
973 Unsupported values will be ignored.
976 .Dv NULL Ns -terminated
977 argument vector to pass to the
979 system call when executing the command.
980 The plugin is responsible for allocating and populating the vector.
983 .Dv NULL Ns -terminated
984 environment vector to use when executing the command.
985 The plugin is responsible for allocating and populating the vector.
988 .Bd -literal -compact
989 int (*list)(int argc, char * const argv[],
990 int verbose, const char *list_user);
993 List available privileges for the invoking user.
994 Returns 1 on success, 0 on failure and \-1 on error.
995 On error, the plugin may optionally call the
1000 .Dv SUDO_CONF_ERROR_MSG
1001 to present additional error information to
1004 Privileges should be output via the
1009 .Dv SUDO_CONV_INFO_MSG ,
1012 Flag indicating whether to list in verbose mode or not.
1014 The name of a different user to list privileges for if the policy
1018 the plugin should list the privileges of the invoking user.
1020 The number of elements in
1022 not counting the final
1027 .No non- Ns Dv NULL ,
1028 an argument vector describing a command the user
1029 wishes to check against the policy in the same form as what would
1033 If the command is permitted by the policy, the fully-qualified path
1034 to the command should be displayed along with any command line arguments.
1037 .Bd -literal -compact
1038 int (*validate)(void);
1043 function is called when
1048 For policy plugins such as
1051 authentication credentials, this function will validate and cache
1058 if the plugin does not support credential caching.
1060 Returns 1 on success, 0 on failure and \-1 on error.
1061 On error, the plugin may optionally call the
1066 .Dv SUDO_CONF_ERROR_MSG
1067 to present additional
1068 error information to the user.
1070 .Bd -literal -compact
1071 void (*invalidate)(int remove);
1076 function is called when
1084 For policy plugins such as
1087 cache authentication credentials, this function will invalidate the
1091 flag is set, the plugin may remove
1092 the credentials instead of simply invalidating them.
1098 if the plugin does not support credential caching.
1100 .Bd -literal -compact
1101 int (*init_session)(struct passwd *pwd, char **user_envp[);
1106 function is called before
1109 execution environment for the command.
1110 It is run in the parent
1112 process and before any uid or gid changes.
1113 This can be used to perform session setup that is not supported by
1115 such as opening the PAM session.
1119 used to tear down the session that was opened by
1124 argument points to a passwd struct for the user the
1125 command will be run as if the uid the command will run as was found
1126 in the password database, otherwise it will be
1131 argument points to the environment the command will
1132 run in, in the form of a
1133 .Dv NULL Ns -terminated
1137 This is the same string passed back to the front end via
1143 function needs to modify the user environment, it should update the
1146 The expected use case is to merge the contents of the PAM environment
1147 (if any) with the contents of
1151 parameter is only available
1152 starting with API version 1.2.
1156 version specified by the
1158 front end before using
1160 Failure to do so may result in a crash.
1162 Returns 1 on success, 0 on failure and \-1 on error.
1163 On error, the plugin may optionally call the
1168 .Dv SUDO_CONF_ERROR_MSG
1169 to present additional
1170 error information to the user.
1172 .Bd -literal -compact
1173 void (*register_hooks)(int version,
1174 int (*register_hook)(struct sudo_hook *hook));
1179 function is called by the sudo front end to
1180 register any hooks the plugin needs.
1181 If the plugin does not support hooks,
1183 should be set to the
1189 argument describes the version of the hooks API
1196 function should be used to register any supported
1197 hooks the plugin needs.
1198 It returns 0 on success, 1 if the hook type is not supported and \-1
1199 if the major version in
1201 does not match the front end's major hook API version.
1204 .Sx Hook function API
1205 section below for more information
1210 function is only available starting
1211 with API version 1.2.
1214 front end doesn't support API
1215 version 1.2 or higher,
1218 .It deregister_hooks
1219 .Bd -literal -compact
1220 void (*deregister_hooks)(int version,
1221 int (*deregister_hook)(struct sudo_hook *hook));
1225 .Fn deregister_hooks
1226 function is called by the sudo front end
1227 to deregister any hooks the plugin has registered.
1228 If the plugin does not support hooks,
1229 .Li deregister_hooks
1230 should be set to the
1236 argument describes the version of the hooks API
1243 function should be used to deregister any
1244 hooks that were put in place by the
1247 If the plugin tries to deregister a hook that the front end does not support,
1249 will return an error.
1252 .Sx Hook function API
1253 section below for more information
1257 .Fn deregister_hooks
1258 function is only available starting
1259 with API version 1.2.
1262 front end doesn't support API
1263 version 1.2 or higher,
1264 .Li deregister_hooks
1268 .Em Policy Plugin Version Macros
1270 /* Plugin API version major/minor. */
1271 #define SUDO_API_VERSION_MAJOR 1
1272 #define SUDO_API_VERSION_MINOR 13
1273 #define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
1274 #define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR,\e
1275 SUDO_API_VERSION_MINOR)
1277 /* Getters and setters for API version */
1278 #define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
1279 #define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
1280 #define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \e
1281 *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
1283 #define SUDO_API_VERSION_SET_MINOR(vp, n) do { \e
1284 *(vp) = (*(vp) & 0xffff0000) | (n); \e
1290 #define SUDO_IO_PLUGIN 2
1291 unsigned int type; /* always SUDO_IO_PLUGIN */
1292 unsigned int version; /* always SUDO_API_VERSION */
1293 int (*open)(unsigned int version, sudo_conv_t conversation,
1294 sudo_printf_t plugin_printf, char * const settings[],
1295 char * const user_info[], char * const command_info[],
1296 int argc, char * const argv[], char * const user_env[],
1297 char * const plugin_options[]);
1298 void (*close)(int exit_status, int error); /* wait status or error */
1299 int (*show_version)(int verbose);
1300 int (*log_ttyin)(const char *buf, unsigned int len);
1301 int (*log_ttyout)(const char *buf, unsigned int len);
1302 int (*log_stdin)(const char *buf, unsigned int len);
1303 int (*log_stdout)(const char *buf, unsigned int len);
1304 int (*log_stderr)(const char *buf, unsigned int len);
1305 void (*register_hooks)(int version,
1306 int (*register_hook)(struct sudo_hook *hook));
1307 void (*deregister_hooks)(int version,
1308 int (*deregister_hook)(struct sudo_hook *hook));
1309 int (*change_winsize)(unsigned int lines, unsigned int cols);
1310 int (*log_suspend)(int signo);
1314 When an I/O plugin is loaded,
1316 runs the command in a pseudo-tty.
1317 This makes it possible to log the input and output from the user's
1319 If any of the standard input, standard output or standard error do not
1320 correspond to a tty,
1322 will open a pipe to capture
1323 the I/O for logging before passing it on.
1325 The log_ttyin function receives the raw user input from the terminal
1326 device (note that this will include input even when echo is disabled,
1327 such as when a password is read).
1328 The log_ttyout function receives output from the pseudo-tty that is
1329 suitable for replaying the user's session at a later time.
1335 functions are only called if the standard input, standard output
1336 or standard error respectively correspond to something other than
1339 Any of the logging functions may be set to the
1341 pointer if no logging is to be performed.
1342 If the open function returns 0, no I/O will be sent to the plugin.
1344 If a logging function returns an error
1346 the running command will be terminated and all of the plugin's logging
1347 functions will be disabled.
1348 Other I/O logging plugins will still receive any remaining
1349 input or output that has not yet been processed.
1351 If an input logging function rejects the data by returning 0, the
1352 command will be terminated and the data will not be passed to the
1353 command, though it will still be sent to any other I/O logging plugins.
1354 If an output logging function rejects the data by returning 0, the
1355 command will be terminated and the data will not be written to the
1356 terminal, though it will still be sent to any other I/O logging plugins.
1358 The io_plugin struct has the following fields:
1363 field should always be set to
1364 .Dv SUDO_IO_PLUGIN .
1368 field should be set to
1369 .Dv SUDO_API_VERSION .
1373 to determine the API version the plugin was
1376 .Bd -literal -compact
1377 int (*open)(unsigned int version, sudo_conv_t conversation,
1378 sudo_printf_t plugin_printf, char * const settings[],
1379 char * const user_info[], char * const command_info[],
1380 int argc, char * const argv[], char * const user_env[],
1381 char * const plugin_options[]);
1386 function is run before the
1393 .Fn change_winsize ,
1396 functions are called.
1397 It is only called if the version is being requested or if the
1400 function has returned successfully.
1401 It returns 1 on success, 0 on failure, \-1 if a general error occurred,
1402 or \-2 if there was a usage error.
1405 will print a usage message before it exits.
1406 If an error occurs, the plugin may optionally call the
1411 .Dv SUDO_CONF_ERROR_MSG
1413 additional error information to the user.
1415 The function arguments are as follows:
1418 The version passed in by
1420 allows the plugin to determine the
1421 major and minor version number of the plugin API supported by
1426 function that may be used by the
1428 function to display version information (see
1433 function may also be used to display additional error message to the user.
1436 function returns 0 on success and \-1 on failure.
1439 .Fn printf Ns -style
1440 function that may be used by the
1442 function to display version information (see
1443 show_version below).
1446 function may also be used to display additional error message to the user.
1449 function returns number of characters printed on success and \-1 on failure.
1451 A vector of user-supplied
1453 settings in the form of
1456 The vector is terminated by a
1459 These settings correspond to flags the user specified when running
1461 As such, they will only be present when the corresponding flag has
1462 been specified on the command line.
1466 the plugin should split on the
1472 field will never include one
1478 .Sx Policy plugin API
1479 section for a list of all possible settings.
1481 A vector of information about the user running the command in the form of
1484 The vector is terminated by a
1490 the plugin should split on the
1496 field will never include one
1502 .Sx Policy plugin API
1503 section for a list of all possible strings.
1505 The number of elements in
1507 not counting the final
1510 It can be zero, when
1516 .No non- Ns Dv NULL ,
1517 an argument vector describing a command the user
1518 wishes to run in the same form as what would be passed to the
1522 The user's environment in the form of a
1523 .Dv NULL Ns -terminated
1530 the plugin should split on the
1536 field will never include one
1541 Any (non-comment) strings immediately after the plugin path are
1542 treated as arguments to the plugin.
1543 These arguments are split on a white space boundary and are passed to
1544 the plugin in the form of a
1545 .Dv NULL Ns -terminated
1547 If no arguments were specified,
1555 parameter is only available starting with
1559 check the API version specified
1562 front end before using
1563 .Em plugin_options .
1564 Failure to do so may result in a crash.
1567 .Bd -literal -compact
1568 void (*close)(int exit_status, int error);
1573 function is called when the command being run by
1577 The function arguments are as follows:
1580 The command's exit status, as returned by the
1589 If the command could not be executed, this is set to the value of
1594 If the command was successfully executed, the value of
1599 .Bd -literal -compact
1600 int (*show_version)(int verbose);
1605 function is called by
1607 when the user specifies
1611 The plugin may display its version information to the user via the
1616 .Dv SUDO_CONV_INFO_MSG .
1617 If the user requests detailed version information, the verbose flag will be set.
1619 Returns 1 on success, 0 on failure, \-1 if a general error occurred,
1620 or \-2 if there was a usage error, although the return value is currently
1623 .Bd -literal -compact
1624 int (*log_ttyin)(const char *buf, unsigned int len);
1629 function is called whenever data can be read from
1630 the user but before it is passed to the running command.
1631 This allows the plugin to reject data if it chooses to (for instance
1632 if the input contains banned content).
1633 Returns 1 if the data should be passed to the command, 0 if the data
1634 is rejected (which will terminate the running command) or \-1 if an
1637 The function arguments are as follows:
1640 The buffer containing user input.
1647 .Bd -literal -compact
1648 int (*log_ttyout)(const char *buf, unsigned int len);
1653 function is called whenever data can be read from
1654 the command but before it is written to the user's terminal.
1655 This allows the plugin to reject data if it chooses to (for instance
1656 if the output contains banned content).
1657 Returns 1 if the data should be passed to the user, 0 if the data is rejected
1658 (which will terminate the running command) or \-1 if an error occurred.
1660 The function arguments are as follows:
1663 The buffer containing command output.
1670 .Bd -literal -compact
1671 int (*log_stdin)(const char *buf, unsigned int len);
1676 function is only used if the standard input does
1677 not correspond to a tty device.
1678 It is called whenever data can be read from the standard input but
1679 before it is passed to the running command.
1680 This allows the plugin to reject data if it chooses to
1681 (for instance if the input contains banned content).
1682 Returns 1 if the data should be passed to the command, 0 if the data is
1683 rejected (which will terminate the running command) or \-1 if an error occurred.
1685 The function arguments are as follows:
1688 The buffer containing user input.
1695 .Bd -literal -compact
1696 int (*log_stdout)(const char *buf, unsigned int len);
1701 function is only used if the standard output does not correspond
1703 It is called whenever data can be read from the command but before
1704 it is written to the standard output.
1705 This allows the plugin to reject data if it chooses to
1706 (for instance if the output contains banned content).
1707 Returns 1 if the data should be passed to the user, 0 if the data is
1708 rejected (which will terminate the running command) or \-1 if an error occurred.
1710 The function arguments are as follows:
1713 The buffer containing command output.
1720 .Bd -literal -compact
1721 int (*log_stderr)(const char *buf, unsigned int len);
1726 function is only used if the standard error does
1727 not correspond to a tty device.
1728 It is called whenever data can be read from the command but before it
1729 is written to the standard error.
1730 This allows the plugin to reject data if it chooses to
1731 (for instance if the output contains banned content).
1732 Returns 1 if the data should be passed to the user, 0 if the data is
1733 rejected (which will terminate the running command) or \-1 if an error occurred.
1735 The function arguments are as follows:
1738 The buffer containing command output.
1746 .Sx Policy plugin API
1747 section for a description of
1748 .Li register_hooks .
1749 .It deregister_hooks
1751 .Sx Policy plugin API
1752 section for a description of
1753 .Li deregister_hooks .
1755 .Bd -literal -compact
1756 int (*change_winsize)(unsigned int lines, unsigned int cols);
1761 function is called whenever the window size of the terminal changes from
1762 the initial values specified in the
1765 Returns \-1 if an error occurred, in which case no further calls to
1769 .Bd -literal -compact
1770 int (*log_suspend)(int signo);
1775 function is called whenever a command is suspended or resumed.
1778 argument is either the signal that caused the command to be suspended or
1780 if the command was resumed.
1781 Logging this information makes it possible to skip the period of time when
1782 the command was suspended during playback of a session.
1783 Returns \-1 if an error occurred, in which case no further calls to
1788 .Em I/O Plugin Version Macros
1791 .Sx Policy plugin API .
1795 front end installs default signal handlers to trap common signals
1796 while the plugin functions are run.
1797 The following signals are trapped by default before the command is
1800 .Bl -bullet -compact -width 1n
1821 If a fatal signal is received before the command is executed,
1823 will call the plugin's
1825 function with an exit status of 128 plus the value of the signal
1827 This allows for consistent logging of commands killed by a signal
1828 for plugins that log such information in their
1831 An exception to this is
1833 which is ignored until the command is executed.
1835 A plugin may temporarily install its own signal handlers but must
1836 restore the original handler before the plugin function returns.
1837 .Ss Hook function API
1838 Beginning with plugin API version 1.2, it is possible to install
1839 hooks for certain functions called by the
1843 Currently, the only supported hooks relate to the handling of
1844 environment variables.
1845 Hooks can be used to intercept attempts to get, set, or remove
1846 environment variables so that these changes can be reflected in
1847 the version of the environment that is used to execute a command.
1848 A future version of the API will support hooking internal
1850 front end functions as well.
1856 are described by the following structure:
1858 typedef int (*sudo_hook_fn_t)();
1861 unsigned int hook_version;
1862 unsigned int hook_type;
1863 sudo_hook_fn_t hook_fn;
1870 structure has the following fields:
1875 field should be set to
1876 .Dv SUDO_HOOK_VERSION .
1880 field may be one of the following supported hook types:
1882 .It Dv SUDO_HOOK_SETENV
1886 Any registered hooks will run before the C library implementation.
1890 be a function that matches the following typedef:
1892 typedef int (*sudo_hook_fn_setenv_t)(const char *name,
1893 const char *value, int overwrite, void *closure);
1896 If the registered hook does not match the typedef the results are
1898 .It Dv SUDO_HOOK_UNSETENV
1902 Any registered hooks will run before the C library implementation.
1906 be a function that matches the following typedef:
1908 typedef int (*sudo_hook_fn_unsetenv_t)(const char *name,
1911 .It Dv SUDO_HOOK_GETENV
1915 Any registered hooks will run before the C library implementation.
1919 be a function that matches the following typedef:
1921 typedef int (*sudo_hook_fn_getenv_t)(const char *name,
1922 char **value, void *closure);
1925 If the registered hook does not match the typedef the results are
1927 .It Dv SUDO_HOOK_PUTENV
1931 Any registered hooks will run before the C library implementation.
1935 be a function that matches the following typedef:
1937 typedef int (*sudo_hook_fn_putenv_t)(char *string,
1941 If the registered hook does not match the typedef the results are
1945 sudo_hook_fn_t hook_fn;
1949 field should be set to the plugin's hook implementation.
1950 The actual function arguments will vary depending on the
1958 .Li struct sudo_hook
1959 is passed as the last function parameter.
1960 This can be used to pass arbitrary data to the plugin's hook implementation.
1962 The function return value may be one of the following:
1964 .It Dv SUDO_HOOK_RET_ERROR
1965 The hook function encountered an error.
1966 .It Dv SUDO_HOOK_RET_NEXT
1967 The hook completed without error, go on to the next hook (including
1968 the native implementation if applicable).
1972 .Dv SUDO_HOOK_RET_NEXT
1973 if the specified variable was not found in the private copy of the environment.
1974 .It Dv SUDO_HOOK_RET_STOP
1975 The hook completed without error, stop processing hooks for this invocation.
1976 This can be used to replace the native implementation.
1979 hook that operates on a private copy of
1980 the environment but leaves
1986 Note that it is very easy to create an infinite loop when hooking
1987 C library functions.
1992 function may create a loop if the
1994 implementation calls
1996 to check the locale.
1997 To prevent this, you may wish to use a static variable in the hook
1998 function to guard against nested calls.
2001 static int in_progress = 0; /* avoid recursion */
2003 return SUDO_HOOK_RET_NEXT;
2007 return SUDO_HOOK_RET_STOP;
2010 .Em Hook API Version Macros
2012 /* Hook API version major/minor */
2013 #define SUDO_HOOK_VERSION_MAJOR 1
2014 #define SUDO_HOOK_VERSION_MINOR 0
2015 #define SUDO_HOOK_VERSION SUDO_API_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\e
2016 SUDO_HOOK_VERSION_MINOR)
2019 For getters and setters see the
2020 .Sx Policy plugin API .
2021 .Ss Remote command execution
2024 front end does not have native support for running remote commands.
2025 However, starting with
2029 option may be used to specify a remote host that is passed
2030 to the policy plugin.
2031 A plugin may also accept a
2035 which will work with older versions of
2037 It is anticipated that remote commands will be supported by executing a
2040 The policy plugin should setup the execution environment such that the
2042 front end will run the helper which, in turn, will connect to the
2043 remote host and run the command.
2045 For example, the policy plugin could utilize
2047 to perform remote command execution.
2048 The helper program would be responsible for running
2050 with the proper options to use a private key or certificate
2051 that the remote host will accept and run a program
2052 on the remote host that would setup the execution environment
2057 functionality must be handled by the policy plugin, not
2059 itself as the front end has no knowledge that a remote command is
2061 This may be addressed in a future revision of the plugin API.
2062 .Ss Conversation API
2063 If the plugin needs to interact with the user, it may do so via the
2066 A plugin should not attempt to read directly from the standard input
2067 or the user's tty (neither of which are guaranteed to exist).
2068 The caller must include a trailing newline in
2070 if one is to be printed.
2073 .Fn printf Ns -style
2074 function is also available that can be used to display informational
2075 or error messages to the user, which is usually more convenient for
2076 simple messages where no use input is required.
2078 .Em Conversation function structures
2080 The conversation function takes as arguments pointers to the following
2083 struct sudo_conv_message {
2084 #define SUDO_CONV_PROMPT_ECHO_OFF 0x0001 /* do not echo user input */
2085 #define SUDO_CONV_PROMPT_ECHO_ON 0x0002 /* echo user input */
2086 #define SUDO_CONV_ERROR_MSG 0x0003 /* error message */
2087 #define SUDO_CONV_INFO_MSG 0x0004 /* informational message */
2088 #define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */
2089 #define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */
2090 #define SUDO_CONV_PREFER_TTY 0x2000 /* flag: use tty if possible */
2096 #define SUDO_CONV_REPL_MAX 255
2098 struct sudo_conv_reply {
2102 typedef int (*sudo_conv_callback_fn_t)(int signo, void *closure);
2103 struct sudo_conv_callback {
2104 unsigned int version;
2106 sudo_conv_callback_fn_t on_suspend;
2107 sudo_conv_callback_fn_t on_resume;
2114 .Fn printf Ns -style
2115 functions are passed
2118 function when the plugin is initialized.
2119 The following type definitions can be used in the declaration of the
2123 typedef int (*sudo_conv_t)(int num_msgs,
2124 const struct sudo_conv_message msgs[],
2125 struct sudo_conv_reply replies[],
2126 struct sudo_conv_callback *callback);
2128 typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
2133 function, the plugin must pass an array of
2134 .Li sudo_conv_message
2139 .Li struct sudo_conv_message
2141 .Li struct sudo_conv_reply
2143 each message in the conversation, that is, both arrays must have the same
2146 .Li struct sudo_conv_reply
2149 member initialized to
2152 .Li struct sudo_conv_callback
2155 should contain function pointers to be called when the
2157 process is suspended and/or resumed during conversation input.
2162 functions are called with the signal that caused
2164 to be suspended and the
2167 .Li struct sudo_conv_callback .
2168 These functions should return 0 on success and \-1 on error.
2169 On error, the conversation will end and the conversation function
2170 will return a value of \-1.
2171 The intended use is to allow the plugin to release resources, such as locks,
2172 that should not be held indefinitely while suspended and then reacquire them
2173 when the process is resumed.
2174 Note that the functions are not actually invoked from within a signal handler.
2178 must be set to one of the following values:
2180 .It SUDO_CONV_PROMPT_ECHO_OFF
2181 Prompt the user for input with echo disabled;
2182 this is generally used for passwords.
2183 The reply will be stored in the
2185 array, and it will never be
2187 .It SUDO_CONV_PROMPT_ECHO_ON
2188 Prompt the user for input with echo enabled.
2189 The reply will be stored in the
2191 array, and it will never be
2193 .It SUDO_CONV_ERROR_MSG
2194 Display an error message.
2195 The message is written to the standard error unless the
2196 .Dv SUDO_CONV_PREFER_TTY
2197 flag is set, in which case it is written to the user's terminal if possible.
2198 .It SUDO_CONV_INFO_MSG
2200 The message is written to the standard output unless the
2201 .Dv SUDO_CONV_PREFER_TTY
2202 flag is set, in which case it is written to the user's terminal if possible.
2203 .It SUDO_CONV_PROMPT_MASK
2204 Prompt the user for input but echo an asterisk character for each
2206 The reply will be stored in the
2208 array, and it will never be
2210 This can be used to provide visual feedback to the user while reading
2211 sensitive information that should not be displayed.
2214 In addition to the above values, the following flag bits may also be set:
2216 .It SUDO_CONV_PROMPT_ECHO_OK
2217 Allow input to be read when echo cannot be disabled
2218 when the message type is
2219 .Dv SUDO_CONV_PROMPT_ECHO_OFF
2221 .Dv SUDO_CONV_PROMPT_MASK .
2224 will refuse to read input if the echo cannot be disabled for those
2226 .It SUDO_CONV_PREFER_TTY
2227 When displaying a message via
2228 .Dv SUDO_CONV_ERROR_MSG
2230 .Dv SUDO_CONV_INFO_MSG ,
2231 try to write the message to the user's terminal.
2232 If the terminal is unavailable, the standard error or standard output
2233 will be used, depending upon whether
2234 The user's terminal is always used when possible for input,
2235 this flag is only used for output.
2236 .Dv SUDO_CONV_ERROR_MSG
2238 .Dv SUDO_CONV_INFO_MSG
2244 in seconds until the prompt will wait for no more input.
2245 A zero value implies an infinite timeout.
2247 The plugin is responsible for freeing the reply buffer located in each
2248 .Li struct sudo_conv_reply ,
2251 .Dv SUDO_CONV_REPL_MAX
2252 represents the maximum length of the reply buffer (not including
2253 the trailing NUL character).
2254 In practical terms, this is the longest password
2257 It is also useful as a maximum value for the
2259 function when clearing passwords filled in by the conversation function.
2262 .Fn printf Ns -style
2263 function uses the same underlying mechanism as the
2265 function but only supports
2266 .Dv SUDO_CONV_INFO_MSG
2268 .Dv SUDO_CONV_ERROR_MSG
2272 It can be more convenient than using the
2274 function if no user reply is needed and supports standard
2278 See the sample plugin for an example of the
2281 .Ss Sudoers group plugin API
2284 plugin supports its own plugin interface to allow non-Unix
2286 This can be used to query a group source other than the standard Unix
2288 Two sample group plugins are bundled with
2294 .Xr sudoers @mansectform@ .
2295 Third party group plugins include a QAS AD plugin available from Quest Software.
2297 A group plugin must declare and populate a
2298 .Li sudoers_group_plugin
2299 struct in the global scope.
2300 This structure contains pointers to the functions that implement plugin
2301 initialization, cleanup and group lookup.
2303 struct sudoers_group_plugin {
2304 unsigned int version;
2305 int (*init)(int version, sudo_printf_t sudo_printf,
2306 char *const argv[]);
2307 void (*cleanup)(void);
2308 int (*query)(const char *user, const char *group,
2309 const struct passwd *pwd);
2314 .Li sudoers_group_plugin
2315 struct has the following fields:
2320 field should be set to GROUP_API_VERSION.
2324 to determine the API version the group plugin
2327 .Bd -literal -compact
2328 int (*init)(int version, sudo_printf_t plugin_printf,
2329 char *const argv[]);
2334 function is called after
2337 before any policy checks.
2338 It returns 1 on success, 0 on failure (or if the plugin is not configured),
2339 and \-1 if a error occurred.
2340 If an error occurs, the plugin may call the
2343 .Dv SUDO_CONF_ERROR_MSG
2344 to present additional error information
2347 The function arguments are as follows:
2350 The version passed in by
2352 allows the plugin to determine the
2353 major and minor version number of the group plugin API supported by
2357 .Fn printf Ns -style
2358 function that may be used to display informational or error message to the user.
2359 Returns the number of characters printed on success and \-1 on failure.
2362 .Dv NULL Ns -terminated
2363 array of arguments generated from the
2367 If no arguments were given,
2373 .Bd -literal -compact
2379 function is called when
2383 The plugin should free any memory it has allocated and close open file handles.
2385 .Bd -literal -compact
2386 int (*query)(const char *user, const char *group,
2387 const struct passwd *pwd);
2392 function is used to ask the group plugin whether
2397 The function arguments are as follows:
2400 The name of the user being looked up in the external group database.
2402 The name of the group being queried.
2404 The password database entry for
2410 present in the password database,
2417 .Em Group API Version Macros
2419 /* Sudoers group plugin version major/minor */
2420 #define GROUP_API_VERSION_MAJOR 1
2421 #define GROUP_API_VERSION_MINOR 0
2422 #define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \e
2423 GROUP_API_VERSION_MINOR)
2425 For getters and setters see the
2426 .Sx Policy plugin API .
2427 .Sh PLUGIN API CHANGELOG
2428 The following revisions have been made to the Sudo Plugin API.
2431 Initial API version.
2432 .It Version 1.1 (sudo 1.8.0)
2433 The I/O logging plugin's
2435 function was modified to take the
2437 list as an argument.
2438 .It Version 1.2 (sudo 1.8.5)
2439 The Policy and I/O logging plugins'
2441 functions are now passed
2442 a list of plugin parameters if any are specified in
2443 .Xr sudo.conf @mansectform@ .
2445 A simple hooks API has been introduced to allow plugins to hook in to the
2446 system's environment handling functions.
2450 Policy plugin function is now passed a pointer
2451 to the user environment which can be updated as needed.
2452 This can be used to merge in environment variables stored in the PAM
2453 handle before a command is run.
2454 .It Version 1.3 (sudo 1.8.7)
2457 entry has been added to the
2465 entries were added to the
2473 functions are now optional.
2474 Previously, a missing
2478 function would result in a crash.
2481 function is defined, a default
2483 function will be provided by the
2485 front end that displays a warning if the command could not be
2490 front end now installs default signal handlers to trap common signals
2491 while the plugin functions are run.
2492 .It Version 1.4 (sudo 1.8.8)
2495 entry was added to the
2498 .It Version 1.5 (sudo 1.8.9)
2501 entry was added to the
2504 .It Version 1.6 (sudo 1.8.11)
2505 The behavior when an I/O logging plugin returns an error
2510 front end took no action when the
2517 function returned an error.
2519 The behavior when an I/O logging plugin returns 0 has changed.
2520 Previously, output from the command would be displayed to the
2521 terminal even if an output logging function returned 0.
2522 .It Version 1.7 (sudo 1.8.12)
2525 entry was added to the
2531 entry now starts with a debug file path name and may occur multiple
2532 times if there are multiple plugin-specific Debug lines in the
2533 .Xr sudo.conf @mansectform@ file.
2534 .It Version 1.8 (sudo 1.8.15)
2536 .Em sudoedit_checkdir
2539 entries were added to the
2542 The default value of
2543 .Em sudoedit_checkdir
2544 was changed to true in sudo 1.8.16.
2548 function now takes a pointer to a
2549 .Li struct sudo_conv_callback
2550 as its fourth argument.
2553 definition has been updated to match.
2554 The plugin must specify that it supports plugin API version 1.8 or higher
2555 to receive a conversation function pointer that supports this argument.
2556 .It Version 1.9 (sudo 1.8.16)
2559 entry was added to the
2562 .It Version 1.10 (sudo 1.8.19)
2565 entry was added to the
2573 entries were added to the
2576 .It Version 1.11 (sudo 1.8.20)
2579 entry was added to the
2582 .It Version 1.12 (sudo 1.8.21)
2585 field was added to the io_plugin struct.
2586 .It Version 1.13 (sudo 1.8.26)
2589 field was added to the io_plugin struct.
2592 .Xr sudo.conf @mansectform@ ,
2593 .Xr sudoers @mansectform@ ,
2594 .Xr sudo @mansectsu@
2596 Many people have worked on
2598 over the years; this version consists of code written primarily by:
2599 .Bd -ragged -offset indent
2603 See the CONTRIBUTORS file in the
2605 distribution (https://www.sudo.ws/contributors.html) for an
2606 exhaustive list of people who have contributed to
2609 If you feel you have found a bug in
2611 please submit a bug report at https://bugzilla.sudo.ws/
2613 Limited free support is available via the sudo-users mailing list,
2614 see https://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
2615 search the archives.
2620 and any express or implied warranties, including, but not limited
2621 to, the implied warranties of merchantability and fitness for a
2622 particular purpose are disclaimed.
2623 See the LICENSE file distributed with
2625 or https://www.sudo.ws/license.html for complete details.