1 Copyright (c) 2009-2012 Todd C. Miller <Todd.Miller@courtesan.com>
3 Permission to use, copy, modify, and distribute this software for any
4 purpose with or without fee is hereby granted, provided that the above
5 copyright notice and this permission notice appear in all copies.
7 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 sudo_plugin - Sudo Plugin API
24 Starting with version 1.8, B<sudo> supports a plugin API
25 for policy and session logging. By default, the I<sudoers> policy
26 plugin and an associated I/O logging plugin are used. Via the plugin
27 API, B<sudo> can be configured to use alternate policy and/or I/O
28 logging plugins provided by third parties. The plugins to be used
29 are specified via the F<@sysconfdir@/sudo.conf> file.
31 The API is versioned with a major and minor number. The minor
32 version number is incremented when additions are made. The major
33 number is incremented when incompatible changes are made. A plugin
34 should be check the version passed to it and make sure that the
35 major version matches.
37 The plugin API is defined by the C<sudo_plugin.h> header file.
39 =head2 The sudo.conf File
41 The F<@sysconfdir@/sudo.conf> file contains plugin configuration directives.
42 Currently, the only supported keyword is the C<Plugin> directive,
43 which causes a plugin plugin to be loaded.
45 A C<Plugin> line consists of the C<Plugin> keyword, followed by the
46 I<symbol_name> and the I<path> to the shared object containing the
47 plugin. The I<symbol_name> is the name of the C<struct policy_plugin>
48 or C<struct io_plugin> in the plugin shared object. The I<path>
49 may be fully qualified or relative. If not fully qualified it is
50 relative to the F<@prefix@/libexec> directory. Any additional
51 parameters after the I<path> are passed as options to the plugin's
52 I<open> function. Lines that don't begin with C<Plugin>, C<Path>,
53 C<Debug> or C<Set> are silently ignored.
55 The same shared object may contain multiple plugins, each with a
56 different symbol name. The shared object file must be owned by uid
57 0 and only writable by its owner. Because of ambiguities that arise
58 from composite policies, only a single policy plugin may be specified.
59 This limitation does not apply to I/O plugins.
62 # Default @sysconfdir@/sudo.conf file
65 # Plugin plugin_name plugin_path plugin_options ...
66 # Path askpass /path/to/askpass
67 # Path noexec /path/to/sudo_noexec.so
68 # Debug sudo /var/log/sudo_debug all@warn
69 # Set disable_coredump true
71 # The plugin_path is relative to @prefix@/libexec unless
73 # The plugin_name corresponds to a global symbol in the plugin
74 # that contains the plugin interface structure.
75 # The plugin_options are optional.
77 Plugin sudoers_policy sudoers.so
78 Plugin sudoers_io sudoers.so
80 =head2 Policy Plugin API
82 A policy plugin must declare and populate a C<policy_plugin> struct
83 in the global scope. This structure contains pointers to the functions
84 that implement the B<sudo> policy checks. The name of the symbol should
85 be specified in F<@sysconfdir@/sudo.conf> along with a path to the plugin
86 so that B<sudo> can load it.
88 struct policy_plugin {
89 #define SUDO_POLICY_PLUGIN 1
90 unsigned int type; /* always SUDO_POLICY_PLUGIN */
91 unsigned int version; /* always SUDO_API_VERSION */
92 int (*open)(unsigned int version, sudo_conv_t conversation,
93 sudo_printf_t plugin_printf, char * const settings[],
94 char * const user_info[], char * const user_env[],
95 char * const plugin_options[]);
96 void (*close)(int exit_status, int error);
97 int (*show_version)(int verbose);
98 int (*check_policy)(int argc, char * const argv[],
99 char *env_add[], char **command_info[],
100 char **argv_out[], char **user_env_out[]);
101 int (*list)(int argc, char * const argv[], int verbose,
102 const char *list_user);
103 int (*validate)(void);
104 void (*invalidate)(int remove);
105 int (*init_session)(struct passwd *pwd, char **user_env[]);
106 void (*register_hooks)(int version,
107 int (*register_hook)(struct sudo_hook *hook));
108 void (*deregister_hooks)(int version,
109 int (*deregister_hook)(struct sudo_hook *hook));
112 The policy_plugin struct has the following fields:
118 The C<type> field should always be set to SUDO_POLICY_PLUGIN.
122 The C<version> field should be set to SUDO_API_VERSION.
124 This allows B<sudo> to determine the API version the plugin was
129 int (*open)(unsigned int version, sudo_conv_t conversation,
130 sudo_printf_t plugin_printf, char * const settings[],
131 char * const user_info[], char * const user_env[],
132 char * const plugin_options[]);
134 Returns 1 on success, 0 on failure, -1 if a general error occurred,
135 or -2 if there was a usage error. In the latter case, B<sudo> will
136 print a usage message before it exits. If an error occurs, the
137 plugin may optionally call the conversation or plugin_printf function
138 with C<SUDO_CONF_ERROR_MSG> to present additional error information
141 The function arguments are as follows:
147 The version passed in by B<sudo> allows the plugin to determine the
148 major and minor version number of the plugin API supported by
153 A pointer to the conversation function that can be used by the
154 plugin to interact with the user (see below).
155 Returns 0 on success and -1 on failure.
159 A pointer to a printf-style function that may be used to display
160 informational or error messages (see below).
161 Returns the number of characters printed on success and -1 on failure.
165 A vector of user-supplied B<sudo> settings in the form of "name=value"
166 strings. The vector is terminated by a C<NULL> pointer. These
167 settings correspond to flags the user specified when running B<sudo>.
168 As such, they will only be present when the corresponding flag has
169 been specified on the command line.
171 When parsing I<settings>, the plugin should split on the B<first>
172 equal sign ('=') since the I<name> field will never include one
173 itself but the I<value> might.
177 =item debug_flags=string
179 A comma-separated list of debug flags that correspond to B<sudo>'s
180 C<Debug> entry in F<@sysconfdir@/sudo.conf>, if there is one. The
181 flags are passed to the plugin as they appear in F<@sysconfdir@/sudo.conf>.
182 The syntax used by B<sudo> and the I<sudoers> plugin is
183 I<subsystem>@I<priority> but the plugin is free to use a different
184 format so long as it does not include a command C<,>.
186 For reference, the priorities supported by the B<sudo> front end and
187 I<sudoers> are: I<crit>, I<err>, I<warn>, I<notice>, I<diag>,
188 I<info>, I<trace> and I<debug>.
190 The following subsystems are defined: I<main>, I<memory>, I<args>,
191 I<exec>, I<pty>, I<utmp>, I<conv>, I<pcomm>, I<util>, I<list>,
192 I<netif>, I<audit>, I<edit>, I<selinux>, I<ldap>, I<match>, I<parser>,
193 I<alias>, I<defaults>, I<auth>, I<env>, I<logging>, I<nss>, I<rbtree>,
194 I<perms>, I<plugin>. The subsystem I<all> includes every subsystem.
196 There is not currently a way to specify a set of debug flags specific
197 to the plugin--the flags are shared by B<sudo> and the plugin.
199 =item debug_level=number
201 This setting has been deprecated in favor of I<debug_flags>.
203 =item runas_user=string
205 The user name or uid to to run the command as, if specified via the
208 =item runas_group=string
210 The group name or gid to to run the command as, if specified via
215 The prompt to use when requesting a password, if specified via
220 Set to true if the user specified the C<-H> flag. If true, set the
221 C<HOME> environment variable to the target user's home directory.
223 =item preserve_environment=bool
225 Set to true if the user specified the C<-E> flag, indicating that
226 the user wishes to preserve the environment.
230 Set to true if the user specified the C<-s> flag, indicating that
231 the user wishes to run a shell.
233 =item login_shell=bool
235 Set to true if the user specified the C<-i> flag, indicating that
236 the user wishes to run a login shell.
238 =item implied_shell=bool
240 If the user does not specify a program on the command line, B<sudo>
241 will pass the plugin the path to the user's shell and set
242 I<implied_shell> to true. This allows B<sudo> with no arguments
243 to be used similarly to L<su(1)>. If the plugin does not to support
244 this usage, it may return a value of -2 from the C<check_policy>
245 function, which will cause B<sudo> to print a usage message and
248 =item preserve_groups=bool
250 Set to true if the user specified the C<-P> flag, indicating that
251 the user wishes to preserve the group vector instead of setting it
252 based on the runas user.
254 =item ignore_ticket=bool
256 Set to true if the user specified the C<-k> flag along with a
257 command, indicating that the user wishes to ignore any cached
258 authentication credentials.
260 =item noninteractive=bool
262 Set to true if the user specified the C<-n> flag, indicating that
263 B<sudo> should operate in non-interactive mode. The plugin may
264 reject a command run in non-interactive mode if user interaction
267 =item login_class=string
269 BSD login class to use when setting resource limits and nice value,
270 if specified by the C<-c> flag.
272 =item selinux_role=string
274 SELinux role to use when executing the command, if specified by
277 =item selinux_type=string
279 SELinux type to use when executing the command, if specified by
282 =item bsdauth_type=string
284 Authentication type, if specified by the C<-a> flag, to use on
285 systems where BSD authentication is supported.
287 =item network_addrs=list
289 A space-separated list of IP network addresses and netmasks in the
290 form "addr/netmask", e.g. "192.168.1.2/255.255.255.0". The address
291 and netmask pairs may be either IPv4 or IPv6, depending on what the
292 operating system supports. If the address contains a colon (':'),
293 it is an IPv6 address, else it is IPv4.
295 =item progname=string
297 The command name that sudo was run as, typically "sudo" or "sudoedit".
301 Set to true when the C<-e> flag is is specified or if invoked as
302 B<sudoedit>. The plugin shall substitute an editor into I<argv>
303 in the I<check_policy> function or return C<-2> with a usage error
304 if the plugin does not support I<sudoedit>. For more information,
305 see the I<check_policy> section.
307 =item closefrom=number
309 If specified, the user has requested via the C<-C> flag that B<sudo>
310 close all files descriptors with a value of I<number> or higher.
311 The plugin may optionally pass this, or another value, back in the
312 I<command_info> list.
316 Additional settings may be added in the future so the plugin should
317 silently ignore settings that it does not recognize.
321 A vector of information about the user running the command in the form of
322 "name=value" strings. The vector is terminated by a C<NULL> pointer.
324 When parsing I<user_info>, the plugin should split on the B<first>
325 equal sign ('=') since the I<name> field will never include one
326 itself but the I<value> might.
332 The process ID of the running B<sudo> process.
333 Only available starting with API version 1.2
337 The parent process ID of the running B<sudo> process.
338 Only available starting with API version 1.2
342 The session ID of the running B<sudo> process or 0 if B<sudo> is
343 not part of a POSIX job control session.
344 Only available starting with API version 1.2
348 The ID of the process group that the running B<sudo> process belongs
350 Only available starting with API version 1.2
354 The ID of the forground process group associated with the terminal
355 device associcated with the B<sudo> process or -1 if there is no
357 Only available starting with API version 1.2
361 The name of the user invoking B<sudo>.
365 The effective user ID of the user invoking B<sudo>.
369 The real user ID of the user invoking B<sudo>.
373 The effective group ID of the user invoking B<sudo>.
377 The real group ID of the user invoking B<sudo>.
381 The user's supplementary group list formatted as a string of
382 comma-separated group IDs.
386 The user's current working directory.
390 The path to the user's terminal device. If the user has no terminal
391 device associated with the session, the value will be empty, as in
396 The local machine's hostname as returned by the C<gethostname()>
401 The number of lines the user's terminal supports. If there is
402 no terminal device available, a default value of 24 is used.
406 The number of columns the user's terminal supports. If there is
407 no terminal device available, a default value of 80 is used.
413 The user's environment in the form of a C<NULL>-terminated vector of
414 "name=value" strings.
416 When parsing I<user_env>, the plugin should split on the B<first>
417 equal sign ('=') since the I<name> field will never include one
418 itself but the I<value> might.
422 Any (non-comment) strings immediately after the plugin path are
423 treated as arguments to the plugin. These arguments are split on
424 a white space boundary and are passed to the plugin in the form of
425 a C<NULL>-terminated array of strings. If no arguments were
426 specified, I<plugin_options> will be the NULL pointer.
428 NOTE: the I<plugin_options> parameter is only available starting with
429 API version 1.2. A plugin B<must> check the API version specified
430 by the B<sudo> front end before using I<plugin_options>. Failure to
431 do so may result in a crash.
437 void (*close)(int exit_status, int error);
439 The C<close> function is called when the command being run by B<sudo>
442 The function arguments are as follows:
448 The command's exit status, as returned by the wait(2) system call.
449 The value of C<exit_status> is undefined if C<error> is non-zero.
453 If the command could not be executed, this is set to the value of
454 C<errno> set by the execve(2) system call. The plugin is responsible
455 for displaying error information via the conversation or plugin_printf
456 function. If the command was successfully executed, the value of
463 int (*show_version)(int verbose);
465 The C<show_version> function is called by B<sudo> when the user specifies
466 the C<-V> option. The plugin may display its version information
467 to the user via the conversation or plugin_printf function using
468 C<SUDO_CONV_INFO_MSG>. If the user requests detailed version
469 information, the verbose flag will be set.
473 int (*check_policy)(int argc, char * const argv[]
474 char *env_add[], char **command_info[],
475 char **argv_out[], char **user_env_out[]);
477 The I<check_policy> function is called by B<sudo> to determine
478 whether the user is allowed to run the specified commands.
480 If the I<sudoedit> option was enabled in the I<settings> array
481 passed to the I<open> function, the user has requested I<sudoedit>
482 mode. I<sudoedit> is a mechanism for editing one or more files
483 where an editor is run with the user's credentials instead of with
484 elevated privileges. B<sudo> achieves this by creating user-writable
485 temporary copies of the files to be edited and then overwriting the
486 originals with the temporary copies after editing is complete. If
487 the plugin supports B<sudoedit>, it should choose the editor to be
488 used, potentially from a variable in the user's environment, such
489 as C<EDITOR>, and include it in I<argv_out> (note that environment
490 variables may include command line flags). The files to be edited
491 should be copied from I<argv> into I<argv_out>, separated from the
492 editor and its arguments by a C<"--"> element. The C<"--"> will
493 be removed by B<sudo> before the editor is executed. The plugin
494 should also set I<sudoedit=true> in the I<command_info> list.
496 The I<check_policy> function returns 1 if the command is allowed,
497 0 if not allowed, -1 for a general error, or -2 for a usage error
498 or if B<sudoedit> was specified but is unsupported by the plugin.
499 In the latter case, B<sudo> will print a usage message before it
500 exits. If an error occurs, the plugin may optionally call the
501 conversation or plugin_printf function with C<SUDO_CONF_ERROR_MSG>
502 to present additional error information to the user.
504 The function arguments are as follows:
510 The number of elements in I<argv>, not counting the final C<NULL>
515 The argument vector describing the command the user wishes to run,
516 in the same form as what would be passed to the execve() system
517 call. The vector is terminated by a C<NULL> pointer.
521 Additional environment variables specified by the user on the command
522 line in the form of a C<NULL>-terminated vector of "name=value"
523 strings. The plugin may reject the command if one or more variables
524 are not allowed to be set, or it may silently ignore such variables.
526 When parsing I<env_add>, the plugin should split on the B<first>
527 equal sign ('=') since the I<name> field will never include one
528 itself but the I<value> might.
532 Information about the command being run in the form of "name=value"
533 strings. These values are used by B<sudo> to set the execution
534 environment when running a command. The plugin is responsible for
535 creating and populating the vector, which must be terminated with
536 a C<NULL> pointer. The following values are recognized by B<sudo>:
542 Fully qualified path to the command to be executed.
546 User ID to run the command as.
550 Effective user ID to run the command as.
551 If not specified, the value of I<runas_uid> is used.
555 Group ID to run the command as.
559 Effective group ID to run the command as.
560 If not specified, the value of I<runas_gid> is used.
562 =item runas_groups=list
564 The supplementary group vector to use for the command in the form
565 of a comma-separated list of group IDs. If I<preserve_groups>
566 is set, this option is ignored.
568 =item login_class=string
570 BSD login class to use when setting resource limits and nice value
571 (optional). This option is only set on systems that support login
574 =item preserve_groups=bool
576 If set, B<sudo> will preserve the user's group vector instead of
577 initializing the group vector based on C<runas_user>.
581 The current working directory to change to when executing the command.
585 If set, prevent the command from executing other programs.
589 The root directory to use when running the command.
593 Nice value (priority) to use when executing the command. The nice
594 value, if specified, overrides the priority associated with the
595 I<login_class> on BSD systems.
599 The file creation mask to use when executing the command.
601 =item selinux_role=string
603 SELinux role to use when executing the command.
605 =item selinux_type=string
607 SELinux type to use when executing the command.
611 Command timeout. If non-zero then when the timeout expires the
612 command will be killed.
616 Set to true when in I<sudoedit> mode. The plugin may enable
617 I<sudoedit> mode even if B<sudo> was not invoked as B<sudoedit>.
618 This allows the plugin to perform command substitution and transparently
619 enable I<sudoedit> when the user attempts to run an editor.
621 =item closefrom=number
623 If specified, B<sudo> will close all files descriptors with a value
624 of I<number> or higher.
626 =item iolog_compress=bool
628 Set to true if the I/O logging plugins, if any, should compress the
629 log data. This is a hint to the I/O logging plugin which may choose
632 =item iolog_path=string
634 Fully qualified path to the file or directory in which I/O log is
635 to be stored. This is a hint to the I/O logging plugin which may
636 choose to ignore it. If no I/O logging plugin is loaded, this
637 setting has no effect.
639 =item iolog_stdin=bool
641 Set to true if the I/O logging plugins, if any, should log the
642 standard input if it is not connected to a terminal device. This
643 is a hint to the I/O logging plugin which may choose to ignore it.
645 =item iolog_stdout=bool
647 Set to true if the I/O logging plugins, if any, should log the
648 standard output if it is not connected to a terminal device. This
649 is a hint to the I/O logging plugin which may choose to ignore it.
651 =item iolog_stderr=bool
653 Set to true if the I/O logging plugins, if any, should log the
654 standard error if it is not connected to a terminal device. This
655 is a hint to the I/O logging plugin which may choose to ignore it.
657 =item iolog_ttyin=bool
659 Set to true if the I/O logging plugins, if any, should log all
660 terminal input. This only includes input typed by the user and not
661 from a pipe or redirected from a file. This is a hint to the I/O
662 logging plugin which may choose to ignore it.
664 =item iolog_ttyout=bool
666 Set to true if the I/O logging plugins, if any, should log all
667 terminal output. This only includes output to the screen, not
668 output to a pipe or file. This is a hint to the I/O logging plugin
669 which may choose to ignore it.
673 Allocate a pseudo-tty to run the command in, regardless of whether
674 or not I/O logging is in use. By default, B<sudo> will only run
675 the command in a pty when an I/O log plugin is loaded.
679 Create a utmp (or utmpx) entry when a pseudo-tty is allocated. By
680 default, the new entry will be a copy of the user's existing utmp
681 entry (if any), with the tty, time, type and pid fields updated.
683 =item utmp_user=string
685 User name to use when constructing a new utmp (or utmpx) entry when
686 I<set_utmp> is enabled. This option can be used to set the user
687 field in the utmp entry to the user the command runs as rather than
688 the invoking user. If not set, B<sudo> will base the new entry on
689 the invoking user's existing entry.
693 Unsupported values will be ignored.
697 The C<NULL>-terminated argument vector to pass to the execve()
698 system call when executing the command. The plugin is responsible
699 for allocating and populating the vector.
703 The C<NULL>-terminated environment vector to use when executing the
704 command. The plugin is responsible for allocating and populating
711 int (*list)(int verbose, const char *list_user,
712 int argc, char * const argv[]);
714 List available privileges for the invoking user. Returns 1 on
715 success, 0 on failure and -1 on error. On error, the plugin may
716 optionally call the conversation or plugin_printf function with
717 C<SUDO_CONF_ERROR_MSG> to present additional error information to
720 Privileges should be output via the conversation or plugin_printf
721 function using C<SUDO_CONV_INFO_MSG>.
727 Flag indicating whether to list in verbose mode or not.
731 The name of a different user to list privileges for if the policy
732 allows it. If C<NULL>, the plugin should list the privileges of
737 The number of elements in I<argv>, not counting the final C<NULL>
742 If non-C<NULL>, an argument vector describing a command the user
743 wishes to check against the policy in the same form as what would
744 be passed to the execve() system call. If the command is permitted
745 by the policy, the fully-qualified path to the command should be
746 displayed along with any command line arguments.
752 int (*validate)(void);
754 The C<validate> function is called when B<sudo> is run with the
755 C<-v> flag. For policy plugins such as I<sudoers> that cache
756 authentication credentials, this function will validate and cache
759 The C<validate> function should be C<NULL> if the plugin does not
760 support credential caching.
762 Returns 1 on success, 0 on failure and -1 on error.
763 On error, the plugin may optionally call the conversation or plugin_printf
764 function with C<SUDO_CONF_ERROR_MSG> to present additional
765 error information to the user.
769 void (*invalidate)(int remove);
771 The C<invalidate> function is called when B<sudo> is called with
772 the C<-k> or C<-K> flag. For policy plugins such as I<sudoers> that
773 cache authentication credentials, this function will invalidate the
774 credentials. If the I<remove> flag is set, the plugin may remove
775 the credentials instead of simply invalidating them.
777 The C<invalidate> function should be C<NULL> if the plugin does not
778 support credential caching.
782 int (*init_session)(struct passwd *pwd, char **user_envp[);
784 The C<init_session> function is called before B<sudo> sets up the
785 execution environment for the command. It is run in the parent
786 B<sudo> process and before any uid or gid changes. This can be used
787 to perform session setup that is not supported by I<command_info>,
788 such as opening the PAM session. The C<close> function can be
789 used to tear down the session that was opened by C<init_session>.
791 The I<pwd> argument points to a passwd struct for the user the
792 command will be run as if the uid the command will run as was found
793 in the password database, otherwise it will be NULL.
795 The I<user_env> argument points to the environment the command will
796 run in, in the form of a C<NULL>-terminated vector of "name=value"
797 strings. This is the same string passed back to the front end via
798 the Policy Plugin's I<user_env_out> parameter. If the C<init_session>
799 function needs to modify the user environment, it should update the
800 pointer stored in I<user_env>. The expected use case is to merge
801 the contents of the PAM environment (if any) with the contents of
802 I<user_env>. NOTE: the I<user_env> parameter is only available
803 starting with API version 1.2. A plugin B<must> check the API
804 version specified by the B<sudo> front end before using I<user_env>.
805 Failure to do so may result in a crash.
807 Returns 1 on success, 0 on failure and -1 on error.
808 On error, the plugin may optionally call the conversation or plugin_printf
809 function with C<SUDO_CONF_ERROR_MSG> to present additional
810 error information to the user.
814 void (*register_hooks)(int version,
815 int (*register_hook)(struct sudo_hook *hook));
817 The C<register_hooks> function is called by the sudo front end to
818 register any hooks the plugin needs. If the plugin does not support
819 hooks, C<register_hooks> should be set to the NULL pointer.
821 The I<version> argument describes the version of the hooks API
822 supported by the B<sudo> front end.
824 The C<register_hook> function should be used to register any supported
825 hooks the plugin needs. It returns 0 on success, 1 if the hook
826 type is not supported and -1 if the major version in C<struct hook>
827 does not match the front end's major hook API version.
829 See the L<Hook Function API> section below for more information
832 NOTE: the C<register_hooks> function is only available starting
833 with API version 1.2. If the B<sudo> front end doesn't support API
834 version 1.2 or higher, C<register_hooks> will not be called.
836 =item deregister_hooks
838 void (*deregister_hooks)(int version,
839 int (*deregister_hook)(struct sudo_hook *hook));
841 The C<deregister_hooks> function is called by the sudo front end
842 to deregister any hooks the plugin has registered. If the plugin
843 does not support hooks, C<deregister_hooks> should be set to the
846 The I<version> argument describes the version of the hooks API
847 supported by the B<sudo> front end.
849 The C<deregister_hook> function should be used to deregister any
850 hooks that were put in place by the C<register_hook> function. If
851 the plugin tries to deregister a hook that the front end does not
852 support, C<deregister_hook> will return an error.
854 See the L<Hook Function API> section below for more information
857 NOTE: the C<deregister_hooks> function is only available starting
858 with API version 1.2. If the B<sudo> front end doesn't support API
859 version 1.2 or higher, C<deregister_hooks> will not be called.
863 =head3 Policy Plugin Version Macros
865 /* Plugin API version major/minor. */
866 #define SUDO_API_VERSION_MAJOR 1
867 #define SUDO_API_VERSION_MINOR 2
868 #define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
869 #define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR,\
870 SUDO_API_VERSION_MINOR)
872 /* Getters and setters for API version */
873 #define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
874 #define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
875 #define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \
876 *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
878 #define SUDO_VERSION_SET_MINOR(vp, n) do { \
879 *(vp) = (*(vp) & 0xffff0000) | (n); \
882 =head2 I/O Plugin API
885 #define SUDO_IO_PLUGIN 2
886 unsigned int type; /* always SUDO_IO_PLUGIN */
887 unsigned int version; /* always SUDO_API_VERSION */
888 int (*open)(unsigned int version, sudo_conv_t conversation
889 sudo_printf_t plugin_printf, char * const settings[],
890 char * const user_info[], int argc, char * const argv[],
891 char * const user_env[], char * const plugin_options[]);
892 void (*close)(int exit_status, int error); /* wait status or error */
893 int (*show_version)(int verbose);
894 int (*log_ttyin)(const char *buf, unsigned int len);
895 int (*log_ttyout)(const char *buf, unsigned int len);
896 int (*log_stdin)(const char *buf, unsigned int len);
897 int (*log_stdout)(const char *buf, unsigned int len);
898 int (*log_stderr)(const char *buf, unsigned int len);
899 void (*register_hooks)(int version,
900 int (*register_hook)(struct sudo_hook *hook));
901 void (*deregister_hooks)(int version,
902 int (*deregister_hook)(struct sudo_hook *hook));
905 When an I/O plugin is loaded, B<sudo> runs the command in a pseudo-tty.
906 This makes it possible to log the input and output from the user's
907 session. If any of the standard input, standard output or standard
908 error do not correspond to a tty, B<sudo> will open a pipe to capture
909 the I/O for logging before passing it on.
911 The log_ttyin function receives the raw user input from the terminal
912 device (note that this will include input even when echo is disabled,
913 such as when a password is read). The log_ttyout function receives
914 output from the pseudo-tty that is suitable for replaying the user's
915 session at a later time. The log_stdin, log_stdout and log_stderr
916 functions are only called if the standard input, standard output
917 or standard error respectively correspond to something other than
920 Any of the logging functions may be set to the NULL
921 pointer if no logging is to be performed. If the open function
922 returns C<0>, no I/O will be sent to the plugin.
924 The io_plugin struct has the following fields:
930 The C<type> field should always be set to SUDO_IO_PLUGIN
934 The C<version> field should be set to SUDO_API_VERSION.
936 This allows B<sudo> to determine the API version the plugin was
941 int (*open)(unsigned int version, sudo_conv_t conversation
942 sudo_printf_t plugin_printf, char * const settings[],
943 char * const user_info[], int argc, char * const argv[],
944 char * const user_env[], char * const plugin_options[]);
946 The I<open> function is run before the I<log_input>, I<log_output>
947 or I<show_version> functions are called. It is only called if the
948 version is being requested or the I<check_policy> function has
949 returned successfully. It returns 1 on success, 0 on failure, -1
950 if a general error occurred, or -2 if there was a usage error. In
951 the latter case, B<sudo> will print a usage message before it exits.
952 If an error occurs, the plugin may optionally call the conversation
953 or plugin_printf function with C<SUDO_CONF_ERROR_MSG> to present
954 additional error information to the user.
956 The function arguments are as follows:
962 The version passed in by B<sudo> allows the plugin to determine the
963 major and minor version number of the plugin API supported by
968 A pointer to the conversation function that may be used by the
969 I<show_version> function to display version information (see
970 show_version below). The conversation function may also be used
971 to display additional error message to the user.
972 The conversation function returns 0 on success and -1 on failure.
976 A pointer to a printf-style function that may be used by the
977 I<show_version> function to display version information (see
978 show_version below). The plugin_printf function may also be used
979 to display additional error message to the user.
980 The plugin_printf function returns number of characters printed on
981 success and -1 on failure.
985 A vector of user-supplied B<sudo> settings in the form of "name=value"
986 strings. The vector is terminated by a C<NULL> pointer. These
987 settings correspond to flags the user specified when running B<sudo>.
988 As such, they will only be present when the corresponding flag has
989 been specified on the command line.
991 When parsing I<settings>, the plugin should split on the B<first>
992 equal sign ('=') since the I<name> field will never include one
993 itself but the I<value> might.
995 See the L<Policy Plugin API> section for a list of all possible settings.
999 A vector of information about the user running the command in the form of
1000 "name=value" strings. The vector is terminated by a C<NULL> pointer.
1002 When parsing I<user_info>, the plugin should split on the B<first>
1003 equal sign ('=') since the I<name> field will never include one
1004 itself but the I<value> might.
1006 See the L<Policy Plugin API> section for a list of all possible strings.
1010 The number of elements in I<argv>, not counting the final C<NULL>
1015 If non-C<NULL>, an argument vector describing a command the user
1016 wishes to run in the same form as what would be passed to the
1017 execve() system call.
1021 The user's environment in the form of a C<NULL>-terminated vector of
1022 "name=value" strings.
1024 When parsing I<user_env>, the plugin should split on the B<first>
1025 equal sign ('=') since the I<name> field will never include one
1026 itself but the I<value> might.
1028 =item plugin_options
1030 Any (non-comment) strings immediately after the plugin path are
1031 treated as arguments to the plugin. These arguments are split on
1032 a white space boundary and are passed to the plugin in the form of
1033 a C<NULL>-terminated array of strings. If no arguments were
1034 specified, I<plugin_options> will be the NULL pointer.
1036 NOTE: the I<plugin_options> parameter is only available starting with
1037 API version 1.2. A plugin B<must> check the API version specified
1038 by the B<sudo> front end before using I<plugin_options>. Failure to
1039 do so may result in a crash.
1045 void (*close)(int exit_status, int error);
1047 The C<close> function is called when the command being run by B<sudo>
1050 The function arguments are as follows:
1056 The command's exit status, as returned by the wait(2) system call.
1057 The value of C<exit_status> is undefined if C<error> is non-zero.
1061 If the command could not be executed, this is set to the value of
1062 C<errno> set by the execve(2) system call. If the command was
1063 successfully executed, the value of C<error> is 0.
1069 int (*show_version)(int verbose);
1071 The C<show_version> function is called by B<sudo> when the user specifies
1072 the C<-V> option. The plugin may display its version information
1073 to the user via the conversation or plugin_printf function using
1074 C<SUDO_CONV_INFO_MSG>. If the user requests detailed version
1075 information, the verbose flag will be set.
1079 int (*log_ttyin)(const char *buf, unsigned int len);
1081 The I<log_ttyin> function is called whenever data can be read from
1082 the user but before it is passed to the running command. This
1083 allows the plugin to reject data if it chooses to (for instance
1084 if the input contains banned content). Returns C<1> if the data
1085 should be passed to the command, C<0> if the data is rejected
1086 (which will terminate the command) or C<-1> if an error occurred.
1088 The function arguments are as follows:
1094 The buffer containing user input.
1098 The length of I<buf> in bytes.
1104 int (*log_ttyout)(const char *buf, unsigned int len);
1106 The I<log_ttyout> function is called whenever data can be read from
1107 the command but before it is written to the user's terminal. This
1108 allows the plugin to reject data if it chooses to (for instance
1109 if the output contains banned content). Returns C<1> if the data
1110 should be passed to the user, C<0> if the data is rejected
1111 (which will terminate the command) or C<-1> if an error occurred.
1113 The function arguments are as follows:
1119 The buffer containing command output.
1123 The length of I<buf> in bytes.
1129 int (*log_stdin)(const char *buf, unsigned int len);
1131 The I<log_stdin> function is only used if the standard input does
1132 not correspond to a tty device. It is called whenever data can be
1133 read from the standard input but before it is passed to the running
1134 command. This allows the plugin to reject data if it chooses to
1135 (for instance if the input contains banned content). Returns C<1>
1136 if the data should be passed to the command, C<0> if the data is
1137 rejected (which will terminate the command) or C<-1> if an error
1140 The function arguments are as follows:
1146 The buffer containing user input.
1150 The length of I<buf> in bytes.
1156 int (*log_stdout)(const char *buf, unsigned int len);
1158 The I<log_stdout> function is only used if the standard output does
1159 not correspond to a tty device. It is called whenever data can be
1160 read from the command but before it is written to the standard
1161 output. This allows the plugin to reject data if it chooses to
1162 (for instance if the output contains banned content). Returns C<1>
1163 if the data should be passed to the user, C<0> if the data is
1164 rejected (which will terminate the command) or C<-1> if an error
1167 The function arguments are as follows:
1173 The buffer containing command output.
1177 The length of I<buf> in bytes.
1183 int (*log_stderr)(const char *buf, unsigned int len);
1185 The I<log_stderr> function is only used if the standard error does
1186 not correspond to a tty device. It is called whenever data can be
1187 read from the command but before it is written to the standard
1188 error. This allows the plugin to reject data if it chooses to
1189 (for instance if the output contains banned content). Returns C<1>
1190 if the data should be passed to the user, C<0> if the data is
1191 rejected (which will terminate the command) or C<-1> if an error
1194 The function arguments are as follows:
1200 The buffer containing command output.
1204 The length of I<buf> in bytes.
1208 =item register_hooks
1210 See the L<Policy Plugin API> section for a description of
1213 =item deregister_hooks
1215 See the L<Policy Plugin API> section for a description of
1216 C<deregister_hooks>.
1220 =head3 I/O Plugin Version Macros
1222 Same as for the L<Policy Plugin API>.
1224 =head2 Hook Function API
1226 Beginning with plugin API version 1.2, it is possible to install
1227 hooks for certain functions called by the B<sudo> front end.
1229 Currently, the only supported hooks relate to the handling of
1230 environment variables. Hooks can be used to intercept attempts to
1231 get, set, or remove environment variables so that these changes can
1232 be reflected in the version of the environment that is used to
1233 execute a command. A future version of the API will support
1234 hooking internal B<sudo> front end functions as well.
1236 =head3 Hook structure
1238 Hooks in B<sudo> are described by the following structure:
1240 typedef int (*sudo_hook_fn_t)();
1245 sudo_hook_fn_t hook_fn;
1249 The C<sudo_hook> structure has the following fields:
1255 The C<hook_version> field should be set to SUDO_HOOK_VERSION.
1259 The C<hook_type> field may be one of the following supported hook types:
1263 =item SUDO_HOOK_SETENV
1265 The C library C<setenv()> function. Any registered hooks will run
1266 before the C library implementation. The C<hook_fn> field should
1267 be a function that matches the following typedef:
1269 typedef int (*sudo_hook_fn_setenv_t)(const char *name,
1270 const char *value, int overwrite, void *closure);
1272 If the registered hook does not match the typedef the results are
1275 =item SUDO_HOOK_UNSETENV
1277 The C library C<unsetenv()> function. Any registered hooks will run
1278 before the C library implementation. The C<hook_fn> field should
1279 be a function that matches the following typedef:
1281 typedef int (*sudo_hook_fn_unsetenv_t)(const char *name,
1284 =item SUDO_HOOK_GETENV
1286 The C library C<getenv()> function. Any registered hooks will run
1287 before the C library implementation. The C<hook_fn> field should
1288 be a function that matches the following typedef:
1290 typedef int (*sudo_hook_fn_getenv_t)(const char *name,
1291 char **value, void *closure);
1293 If the registered hook does not match the typedef the results are
1296 =item SUDO_HOOK_PUTENV
1298 The C library C<putenv()> function. Any registered hooks will run
1299 before the C library implementation. The C<hook_fn> field should
1300 be a function that matches the following typedef:
1302 typedef int (*sudo_hook_fn_putenv_t)(char *string,
1305 If the registered hook does not match the typedef the results are
1312 sudo_hook_fn_t hook_fn;
1314 The C<hook_fn> field should be set to the plugin's hook implementation.
1315 The actual function arguments will vary depending on the C<hook_type>
1316 (see C<hook_type> above). In all cases, the C<closure> field of
1317 C<struct sudo_hook> is passed as the last function parameter. This
1318 can be used to pass arbitrary data to the plugin's hook implementation.
1320 The function return value may be one of the following:
1324 =item SUDO_HOOK_RET_ERROR
1326 The hook function encountered an error.
1328 =item SUDO_HOOK_RET_NEXT
1330 The hook completed without error, go on to the next hook (including
1331 the native implementation if applicable). For example, a C<getenv>
1332 hook might return C<SUDO_HOOK_RET_NEXT> if the specified variable
1333 was not found in the private copy of the environment.
1335 =item SUDO_HOOK_RET_STOP
1337 The hook completed without error, stop processing hooks for this
1338 invocation. This can be used to replace the native implementation.
1339 For example, a C<setenv> hook that operates on a private copy of
1340 the environment but leaves C<environ> unchanged.
1346 Note that it is very easy to create an infinite loop when hooking
1347 C library functions. For example, a C<getenv> hook that calls the
1348 C<snprintf> function may create a loop if the C<snprintf> implementation
1349 calls C<getenv> to check the locale. To prevent this, you may wish
1350 to use a static variable in the hook function to guard against
1353 static int in_progress = 0; /* avoid recursion */
1355 return SUDO_HOOK_RET_NEXT;
1359 return SUDO_HOOK_RET_STOP;
1361 =head3 Hook API Version Macros
1363 /* Hook API version major/minor */
1364 #define SUDO_HOOK_VERSION_MAJOR 1
1365 #define SUDO_HOOK_VERSION_MINOR 0
1366 #define SUDO_HOOK_MKVERSION(x, y) ((x << 16) | y)
1367 #define SUDO_HOOK_VERSION SUDO_HOOK_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\
1368 SUDO_HOOK_VERSION_MINOR)
1370 /* Getters and setters for hook API version */
1371 #define SUDO_HOOK_VERSION_GET_MAJOR(v) ((v) >> 16)
1372 #define SUDO_HOOK_VERSION_GET_MINOR(v) ((v) & 0xffff)
1373 #define SUDO_HOOK_VERSION_SET_MAJOR(vp, n) do { \
1374 *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
1376 #define SUDO_HOOK_VERSION_SET_MINOR(vp, n) do { \
1377 *(vp) = (*(vp) & 0xffff0000) | (n); \
1380 =head2 Conversation API
1382 If the plugin needs to interact with the user, it may do so via the
1383 conversation function. A plugin should not attempt to read directly
1384 from the standard input or the user's tty (neither of which are
1385 guaranteed to exist). The caller must include a trailing newline
1386 in C<msg> if one is to be printed.
1388 A printf-style function is also available that can be used to display
1389 informational or error messages to the user, which is usually more
1390 convenient for simple messages where no use input is required.
1392 struct sudo_conv_message {
1393 #define SUDO_CONV_PROMPT_ECHO_OFF 0x0001 /* do not echo user input */
1394 #define SUDO_CONV_PROMPT_ECHO_ON 0x0002 /* echo user input */
1395 #define SUDO_CONV_ERROR_MSG 0x0003 /* error message */
1396 #define SUDO_CONV_INFO_MSG 0x0004 /* informational message */
1397 #define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */
1398 #define SUDO_CONV_DEBUG_MSG 0x0006 /* debugging message */
1399 #define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */
1405 struct sudo_conv_reply {
1409 typedef int (*sudo_conv_t)(int num_msgs,
1410 const struct sudo_conv_message msgs[],
1411 struct sudo_conv_reply replies[]);
1413 typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
1415 Pointers to the conversation and printf-style functions are passed
1416 in to the plugin's C<open> function when the plugin is initialized.
1418 To use the conversation function, the plugin must pass an array of
1419 C<sudo_conv_message> and C<sudo_conv_reply> structures. There must
1420 be a C<struct sudo_conv_message> and C<struct sudo_conv_reply> for
1421 each message in the conversation. The plugin is responsible for
1422 freeing the reply buffer filled in to the C<struct sudo_conv_reply>,
1425 The printf-style function uses the same underlying mechanism as the
1426 conversation function but only supports C<SUDO_CONV_INFO_MSG>,
1427 C<SUDO_CONV_ERROR_MSG> and C<SUDO_CONV_DEBUG_MSG> for the I<msg_type>
1428 parameter. It can be more convenient than using the conversation
1429 function if no user reply is needed and supports standard printf()
1432 Unlike, C<SUDO_CONV_INFO_MSG> and C<SUDO_CONV_ERROR_MSG>, messages
1433 sent with the <SUDO_CONV_DEBUG_MSG> I<msg_type> are not directly
1434 user-visible. Instead, they are logged to the file specified in
1435 the C<Debug> statement (if any) in the F<@sysconfdir@/sudo.conf>
1436 file. This allows a plugin to log debugging information and is
1437 intended to be used in conjunction with the I<debug_flags> setting.
1439 See the sample plugin for an example of the conversation function usage.
1441 =head2 Sudoers Group Plugin API
1443 The I<sudoers> module supports a plugin interface to allow non-Unix
1444 group lookups. This can be used to query a group source other than
1445 the standard Unix group database. A sample group plugin is bundled
1446 with B<sudo> that implements file-based lookups. Third party group
1447 plugins include a QAS AD plugin available from Quest Software.
1449 A group plugin must declare and populate a C<sudoers_group_plugin>
1450 struct in the global scope. This structure contains pointers to
1451 the functions that implement plugin initialization, cleanup and
1454 struct sudoers_group_plugin {
1455 unsigned int version;
1456 int (*init)(int version, sudo_printf_t sudo_printf,
1457 char *const argv[]);
1458 void (*cleanup)(void);
1459 int (*query)(const char *user, const char *group,
1460 const struct passwd *pwd);
1463 The C<sudoers_group_plugin> struct has the following fields:
1469 The C<version> field should be set to GROUP_API_VERSION.
1471 This allows I<sudoers> to determine the API version the group plugin
1476 int (*init)(int version, sudo_printf_t plugin_printf,
1477 char *const argv[]);
1479 The I<init> function is called after I<sudoers> has been parsed but
1480 before any policy checks. It returns 1 on success, 0 on failure
1481 (or if the plugin is not configured), and -1 if a error occurred.
1482 If an error occurs, the plugin may call the plugin_printf function
1483 with C<SUDO_CONF_ERROR_MSG> to present additional error information
1486 The function arguments are as follows:
1492 The version passed in by I<sudoers> allows the plugin to determine the
1493 major and minor version number of the group plugin API supported by
1498 A pointer to a printf-style function that may be used to display
1499 informational or error message to the user.
1500 Returns the number of characters printed on success and -1 on failure.
1504 A NULL-terminated array of arguments generated from the I<group_plugin>
1505 option in I<sudoers>. If no arguments were given, I<argv> will be
1514 The I<cleanup> function is called when I<sudoers> has finished its
1515 group checks. The plugin should free any memory it has allocated
1516 and close open file handles.
1520 int (*query)(const char *user, const char *group,
1521 const struct passwd *pwd);
1523 The I<query> function is used to ask the group plugin whether I<user>
1524 is a member of I<group>.
1526 The function arguments are as follows:
1532 The name of the user being looked up in the external group database.
1536 The name of the group being queried.
1540 The password database entry for I<user>, if any. If I<user> is not
1541 present in the password database, I<pwd> will be C<NULL>.
1547 =head3 Group API Version Macros
1549 /* Sudoers group plugin version major/minor */
1550 #define GROUP_API_VERSION_MAJOR 1
1551 #define GROUP_API_VERSION_MINOR 0
1552 #define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \
1553 GROUP_API_VERSION_MINOR)
1555 /* Getters and setters for group version */
1556 #define GROUP_API_VERSION_GET_MAJOR(v) ((v) >> 16)
1557 #define GROUP_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
1558 #define GROUP_API_VERSION_SET_MAJOR(vp, n) do { \
1559 *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
1561 #define GROUP_API_VERSION_SET_MINOR(vp, n) do { \
1562 *(vp) = (*(vp) & 0xffff0000) | (n); \
1565 =head1 PLUGIN API CHANGELOG
1567 The following revisions have been made to the Sudo Plugin API.
1573 Initial API version.
1577 The I/O logging plugin's C<open> function was modified to take the
1578 C<command_info> list as an argument.
1582 The Policy and I/O logging plugins' C<open> functions are now passed
1583 a list of plugin options if any are specified in F<@sysconfdir@/sudo.conf>.
1585 A simple hooks API has been introduced to allow plugins to hook in to the
1586 system's environment handling functions.
1588 The C<init_session> Policy plugin function is now passed a pointer
1589 to the user environment which can be updated as needed. This can
1590 be used to merge in environment variables stored in the PAM handle
1591 before a command is run.
1598 L<sudoers(5)>, L<sudo(8)>
1602 If you feel you have found a bug in B<sudo>, please submit a bug report
1603 at http://www.sudo.ws/sudo/bugs/
1607 Limited free support is available via the sudo-workers mailing list,
1608 see http://www.sudo.ws/mailman/listinfo/sudo-workers to subscribe or
1609 search the archives.
1613 B<sudo> is provided ``AS IS'' and any express or implied warranties,
1614 including, but not limited to, the implied warranties of merchantability
1615 and fitness for a particular purpose are disclaimed. See the LICENSE
1616 file distributed with B<sudo> or http://www.sudo.ws/sudo/license.html
1617 for complete details.