2 .\" Copyright (c) 2009-2012 Todd C. Miller <Todd.Miller@courtesan.com>
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.
15 .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
18 .Dt SUDO_PLUGIN @mansectform@
19 .Os Sudo @PACKAGE_VERSION@
24 Starting with version 1.8,
27 for policy and session logging.
30 policy plugin and an associated I/O logging plugin are used.
33 can be configured to use alternate policy and/or I/O logging plugins
34 provided by third parties.
35 The plugins to be used are specified via the
36 .Pa @sysconfdir@/sudo.conf
39 The API is versioned with a major and minor number.
40 The minor version number is incremented when additions are made.
41 The major number is incremented when incompatible changes are made.
42 A plugin should be check the version passed to it and make sure that the
43 major version matches.
45 The plugin API is defined by the
48 .Ss The sudo.conf file
50 .Pa @sysconfdir@/sudo.conf
51 file contains plugin configuration directives.
52 The primary keyword is the
54 directive, which causes a plugin to be loaded.
60 keyword, followed by the
64 to the shared object containing the plugin.
68 .Li struct policy_plugin
71 in the plugin shared object.
74 may be fully qualified or relative.
75 If not fully qualified it is relative to the
78 Any additional parameters after the
80 are passed as options to the plugin's
83 Lines that don't begin with
91 The same shared object may contain multiple plugins, each with a
92 different symbol name.
93 The shared object file must be owned by uid 0 and only writable by its owner.
94 Because of ambiguities that arise from composite policies, only a single
95 policy plugin may be specified.
96 This limitation does not apply to I/O plugins.
99 # Default @sysconfdir@/sudo.conf file
102 # Plugin plugin_name plugin_path plugin_options ...
103 # Path askpass /path/to/askpass
104 # Path noexec /path/to/sudo_noexec.so
105 # Debug sudo /var/log/sudo_debug all@warn
106 # Set disable_coredump true
108 # The plugin_path is relative to @prefix@/libexec unless
110 # The plugin_name corresponds to a global symbol in the plugin
111 # that contains the plugin interface structure.
112 # The plugin_options are optional.
114 Plugin sudoers_policy sudoers.so
115 Plugin sudoers_io sudoers.so
117 .Ss Policy plugin API
118 A policy plugin must declare and populate a
120 struct in the global scope.
121 This structure contains pointers to the functions that implement the
124 The name of the symbol should be specified in
125 .Pa @sysconfdir@/sudo.conf
126 along with a path to the plugin so that
130 struct policy_plugin {
131 #define SUDO_POLICY_PLUGIN 1
132 unsigned int type; /* always SUDO_POLICY_PLUGIN */
133 unsigned int version; /* always SUDO_API_VERSION */
134 int (*open)(unsigned int version, sudo_conv_t conversation,
135 sudo_printf_t plugin_printf, char * const settings[],
136 char * const user_info[], char * const user_env[],
137 char * const plugin_options[]);
138 void (*close)(int exit_status, int error);
139 int (*show_version)(int verbose);
140 int (*check_policy)(int argc, char * const argv[],
141 char *env_add[], char **command_info[],
142 char **argv_out[], char **user_env_out[]);
143 int (*list)(int argc, char * const argv[], int verbose,
144 const char *list_user);
145 int (*validate)(void);
146 void (*invalidate)(int remove);
147 int (*init_session)(struct passwd *pwd, char **user_env[]);
148 void (*register_hooks)(int version,
149 int (*register_hook)(struct sudo_hook *hook));
150 void (*deregister_hooks)(int version,
151 int (*deregister_hook)(struct sudo_hook *hook));
155 The policy_plugin struct has the following fields:
160 field should always be set to SUDO_POLICY_PLUGIN.
164 field should be set to
165 .Dv SUDO_API_VERSION .
169 to determine the API version the plugin was
172 .Bd -literal -compact
173 int (*open)(unsigned int version, sudo_conv_t conversation,
174 sudo_printf_t plugin_printf, char * const settings[],
175 char * const user_info[], char * const user_env[],
176 char * const plugin_options[]);
179 Returns 1 on success, 0 on failure, \-1 if a general error occurred,
180 or \-2 if there was a usage error.
183 will print a usage message before it exits.
184 If an error occurs, the plugin may optionally call the
189 .Dv SUDO_CONF_ERROR_MSG
190 to present additional error information to the user.
192 The function arguments are as follows:
195 The version passed in by
197 allows the plugin to determine the
198 major and minor version number of the plugin API supported by
203 function that can be used by the plugin to interact with the user (see below).
204 Returns 0 on success and \-1 on failure.
207 .Fn printf Ns No -style
208 function that may be used to display informational or error messages
210 Returns the number of characters printed on success and \-1 on failure.
212 A vector of user-supplied
214 settings in the form of
217 The vector is terminated by a
220 These settings correspond to flags the user specified when running
222 As such, they will only be present when the corresponding flag has
223 been specified on the command line.
227 the plugin should split on the
233 field will never include one
238 .It debug_flags=string
239 A comma-separated list of debug flags that correspond to
243 .Pa @sysconfdir@/sudo.conf ,
245 The flags are passed to the plugin as they appear in
246 .Pa @sysconfdir@/sudo.conf .
252 .Em subsystem Ns No @ Ns Em priority
253 but the plugin is free to use a different
254 format so long as it does not include a comma
257 For reference, the priorities supported by the
272 The following subsystems are defined:
301 includes every subsystem.
303 There is not currently a way to specify a set of debug flags specific
304 to the plugin--the flags are shared by
307 .It debug_level=number
308 This setting has been deprecated in favor of
310 .It runas_user=string
311 The user name or uid to to run the command as, if specified via the
314 .It runas_group=string
315 The group name or gid to to run the command as, if specified via
320 The prompt to use when requesting a password, if specified via
325 Set to true if the user specified the
330 environment variable to the target user's home directory.
331 .It preserve_environment=bool
332 Set to true if the user specified the
334 flag, indicating that
335 the user wishes to preserve the environment.
337 Set to true if the user specified the
339 flag, indicating that
340 the user wishes to run a shell.
342 Set to true if the user specified the
344 flag, indicating that
345 the user wishes to run a login shell.
346 .It implied_shell=bool
347 If the user does not specify a program on the command line,
349 will pass the plugin the path to the user's shell and set
355 to be used similarly to
357 If the plugin does not to support this usage, it may return a value of \-2
360 function, which will cause
362 to print a usage message and
364 .It preserve_groups=bool
365 Set to true if the user specified the
367 flag, indicating that
368 the user wishes to preserve the group vector instead of setting it
369 based on the runas user.
370 .It ignore_ticket=bool
371 Set to true if the user specified the
374 command, indicating that the user wishes to ignore any cached
375 authentication credentials.
376 .It noninteractive=bool
377 Set to true if the user specified the
379 flag, indicating that
381 should operate in non-interactive mode.
382 The plugin may reject a command run in non-interactive mode if user
383 interaction is required.
384 .It login_class=string
385 BSD login class to use when setting resource limits and nice value,
389 .It selinux_role=string
390 SELinux role to use when executing the command, if specified by
394 .It selinux_type=string
395 SELinux type to use when executing the command, if specified by
399 .It bsdauth_type=string
400 Authentication type, if specified by the
403 systems where BSD authentication is supported.
404 .It network_addrs=list
405 A space-separated list of IP network addresses and netmasks in the
409 .Dq 192.168.1.2/255.255.255.0 .
410 The address and netmask pairs may be either IPv4 or IPv6, depending on
411 what the operating system supports.
412 If the address contains a colon
414 it is an IPv6 address, else it is IPv4.
416 The command name that sudo was run as, typically
423 flag is is specified or if invoked as
425 The plugin shall substitute an editor into
429 function or return \-2 with a usage error
430 if the plugin does not support
432 For more information, see the
436 If specified, the user has requested via the
440 close all files descriptors with a value of
443 The plugin may optionally pass this, or another value, back in the
448 Additional settings may be added in the future so the plugin should
449 silently ignore settings that it does not recognize.
451 A vector of information about the user running the command in the form of
454 The vector is terminated by a
460 the plugin should split on the
466 field will never include one
472 The process ID of the running
475 Only available starting with API version 1.2
477 The parent process ID of the running
480 Only available starting with API version 1.2
482 The session ID of the running
487 not part of a POSIX job control session.
488 Only available starting with API version 1.2
490 The ID of the process group that the running
494 Only available starting with API version 1.2
496 The ID of the forground process group associated with the terminal
497 device associcated with the
499 process or \-1 if there is no
501 Only available starting with API version 1.2
503 The name of the user invoking
506 The effective user ID of the user invoking
509 The real user ID of the user invoking
512 The effective group ID of the user invoking
515 The real group ID of the user invoking
518 The user's supplementary group list formatted as a string of
519 comma-separated group IDs.
521 The user's current working directory.
523 The path to the user's terminal device.
524 If the user has no terminal device associated with the session,
525 the value will be empty, as in
528 The local machine's hostname as returned by the
532 The number of lines the user's terminal supports.
534 no terminal device available, a default value of 24 is used.
536 The number of columns the user's terminal supports.
537 If there is no terminal device available, a default value of 80 is used.
540 The user's environment in the form of a
541 .Dv NULL Ns No -terminated vector of
547 the plugin should split on the
553 field will never include one
558 Any (non-comment) strings immediately after the plugin path are
559 treated as arguments to the plugin.
560 These arguments are split on a white space boundary and are passed to
561 the plugin in the form of a
562 .Dv NULL Ns No -terminated
573 parameter is only available starting with
577 check the API version specified
580 front end before using
582 Failure to do so may result in a crash.
585 .Bd -literal -compact
586 void (*close)(int exit_status, int error);
591 function is called when the command being run by
595 The function arguments are as follows:
598 The command's exit status, as returned by the
607 If the command could not be executed, this is set to the value of
612 The plugin is responsible for displaying error information via the
617 If the command was successfully executed, the value of
622 .Bd -literal -compact
623 int (*show_version)(int verbose);
628 function is called by
630 when the user specifies
634 The plugin may display its version information to the user via the
639 .Dv SUDO_CONV_INFO_MSG .
640 If the user requests detailed version information, the verbose flag will be set.
642 .Bd -literal -compact
643 int (*check_policy)(int argc, char * const argv[]
644 char *env_add[], char **command_info[],
645 char **argv_out[], char **user_env_out[]);
650 function is called by
653 whether the user is allowed to run the specified commands.
657 option was enabled in the
662 function, the user has requested
666 is a mechanism for editing one or more files
667 where an editor is run with the user's credentials instead of with
670 achieves this by creating user-writable
671 temporary copies of the files to be edited and then overwriting the
672 originals with the temporary copies after editing is complete.
673 If the plugin supports
675 it should choose the editor to be used, potentially from a variable
676 in the user's environment, such as
680 (note that environment
681 variables may include command line flags).
682 The files to be edited should be copied from
687 editor and its arguments by a
695 before the editor is executed.
696 The plugin should also set
704 function returns 1 if the command is allowed,
705 0 if not allowed, \-1 for a general error, or \-2 for a usage error
708 was specified but is unsupported by the plugin.
711 will print a usage message before it
713 If an error occurs, the plugin may optionally call the
718 .Dv SUDO_CONF_ERROR_MSG
719 to present additional error information to the user.
721 The function arguments are as follows:
724 The number of elements in
726 not counting the final
730 The argument vector describing the command the user wishes to run,
731 in the same form as what would be passed to the
734 The vector is terminated by a
738 Additional environment variables specified by the user on the command
739 line in the form of a
740 .Dv NULL Ns No -terminated
744 The plugin may reject the command if one or more variables
745 are not allowed to be set, or it may silently ignore such variables.
749 the plugin should split on the
755 field will never include one
760 Information about the command being run in the form of
763 These values are used by
766 environment when running a command.
767 The plugin is responsible for creating and populating the vector,
768 which must be terminated with a
771 The following values are recognized by
775 Fully qualified path to the command to be executed.
777 User ID to run the command as.
779 Effective user ID to run the command as.
780 If not specified, the value of
784 Group ID to run the command as.
786 Effective group ID to run the command as.
787 If not specified, the value of
790 .It runas_groups=list
791 The supplementary group vector to use for the command in the form
792 of a comma-separated list of group IDs.
795 is set, this option is ignored.
796 .It login_class=string
797 BSD login class to use when setting resource limits and nice value
799 This option is only set on systems that support login classes.
800 .It preserve_groups=bool
803 will preserve the user's group vector instead of
804 initializing the group vector based on
807 The current working directory to change to when executing the command.
809 If set, prevent the command from executing other programs.
811 The root directory to use when running the command.
813 Nice value (priority) to use when executing the command.
814 The nice value, if specified, overrides the priority associated with the
818 The file creation mask to use when executing the command.
819 .It selinux_role=string
820 SELinux role to use when executing the command.
821 .It selinux_type=string
822 SELinux type to use when executing the command.
825 If non-zero then when the timeout expires the command will be killed.
830 The plugin may enable
836 This allows the plugin to perform command substitution and transparently
839 when the user attempts to run an editor.
843 will close all files descriptors with a value
847 .It iolog_compress=bool
848 Set to true if the I/O logging plugins, if any, should compress the
850 This is a hint to the I/O logging plugin which may choose to ignore it.
851 .It iolog_path=string
852 Fully qualified path to the file or directory in which I/O log is
854 This is a hint to the I/O logging plugin which may choose to ignore it.
855 If no I/O logging plugin is loaded, this setting has no effect.
857 Set to true if the I/O logging plugins, if any, should log the
858 standard input if it is not connected to a terminal device.
859 This is a hint to the I/O logging plugin which may choose to ignore it.
860 .It iolog_stdout=bool
861 Set to true if the I/O logging plugins, if any, should log the
862 standard output if it is not connected to a terminal device.
863 This is a hint to the I/O logging plugin which may choose to ignore it.
864 .It iolog_stderr=bool
865 Set to true if the I/O logging plugins, if any, should log the
866 standard error if it is not connected to a terminal device.
867 This is a hint to the I/O logging plugin which may choose to ignore it.
869 Set to true if the I/O logging plugins, if any, should log all
871 This only includes input typed by the user and not from a pipe or
872 redirected from a file.
873 This is a hint to the I/O logging plugin which may choose to ignore it.
874 .It iolog_ttyout=bool
875 Set to true if the I/O logging plugins, if any, should log all
877 This only includes output to the screen, not output to a pipe or file.
878 This is a hint to the I/O logging plugin which may choose to ignore it.
880 Allocate a pseudo-tty to run the command in, regardless of whether
881 or not I/O logging is in use.
885 the command in a pty when an I/O log plugin is loaded.
887 Create a utmp (or utmpx) entry when a pseudo-tty is allocated.
888 By default, the new entry will be a copy of the user's existing utmp
889 entry (if any), with the tty, time, type and pid fields updated.
891 User name to use when constructing a new utmp (or utmpx) entry when
894 This option can be used to set the user field in the utmp entry to
895 the user the command runs as rather than the invoking user.
898 will base the new entry on
899 the invoking user's existing entry.
902 Unsupported values will be ignored.
905 .Dv NULL Ns No -terminated
906 argument vector to pass to the
908 system call when executing the command.
909 The plugin is responsible for allocating and populating the vector.
912 .Dv NULL Ns No -terminated
913 environment vector to use when executing the command.
914 The plugin is responsible for allocating and populating the vector.
917 .Bd -literal -compact
918 int (*list)(int verbose, const char *list_user,
919 int argc, char * const argv[]);
922 List available privileges for the invoking user.
923 Returns 1 on success, 0 on failure and \-1 on error.
924 On error, the plugin may optionally call the
929 .Dv SUDO_CONF_ERROR_MSG
930 to present additional error information to
933 Privileges should be output via the
938 .Dv SUDO_CONV_INFO_MSG ,
941 Flag indicating whether to list in verbose mode or not.
943 The name of a different user to list privileges for if the policy
947 the plugin should list the privileges of the invoking user.
949 The number of elements in
951 not counting the final
956 .No non- Ns Dv NULL ,
957 an argument vector describing a command the user
958 wishes to check against the policy in the same form as what would
962 If the command is permitted by the policy, the fully-qualified path
963 to the command should be displayed along with any command line arguments.
966 .Bd -literal -compact
967 int (*validate)(void);
972 function is called when
977 For policy plugins such as
980 authentication credentials, this function will validate and cache
987 if the plugin does not support credential caching.
989 Returns 1 on success, 0 on failure and \-1 on error.
990 On error, the plugin may optionally call the
995 .Dv SUDO_CONF_ERROR_MSG
996 to present additional
997 error information to the user.
999 .Bd -literal -compact
1000 void (*invalidate)(int remove);
1005 function is called when
1013 For policy plugins such as
1016 cache authentication credentials, this function will invalidate the
1020 flag is set, the plugin may remove
1021 the credentials instead of simply invalidating them.
1027 if the plugin does not support credential caching.
1029 .Bd -literal -compact
1030 int (*init_session)(struct passwd *pwd, char **user_envp[);
1035 function is called before
1038 execution environment for the command.
1039 It is run in the parent
1041 process and before any uid or gid changes.
1042 This can be used to perform session setup that is not supported by
1044 such as opening the PAM session.
1048 used to tear down the session that was opened by
1053 argument points to a passwd struct for the user the
1054 command will be run as if the uid the command will run as was found
1055 in the password database, otherwise it will be
1060 argument points to the environment the command will
1061 run in, in the form of a
1062 .Dv NULL Ns No -terminated
1066 This is the same string passed back to the front end via
1072 function needs to modify the user environment, it should update the
1075 The expected use case is to merge the contents of the PAM environment
1076 (if any) with the contents of
1080 parameter is only available
1081 starting with API version 1.2.
1085 version specified by the
1087 front end before using
1089 Failure to do so may result in a crash.
1091 Returns 1 on success, 0 on failure and \-1 on error.
1092 On error, the plugin may optionally call the
1097 .Dv SUDO_CONF_ERROR_MSG
1098 to present additional
1099 error information to the user.
1101 .Bd -literal -compact
1102 void (*register_hooks)(int version,
1103 int (*register_hook)(struct sudo_hook *hook));
1108 function is called by the sudo front end to
1109 register any hooks the plugin needs.
1110 If the plugin does not support hooks,
1112 should be set to the
1118 argument describes the version of the hooks API
1125 function should be used to register any supported
1126 hooks the plugin needs.
1127 It returns 0 on success, 1 if the hook type is not supported and \-1
1128 if the major version in
1130 does not match the front end's major hook API version.
1133 .Sx Hook function API
1134 section below for more information
1139 function is only available starting
1140 with API version 1.2.
1143 front end doesn't support API
1144 version 1.2 or higher,
1147 .It deregister_hooks
1148 .Bd -literal -compact
1149 void (*deregister_hooks)(int version,
1150 int (*deregister_hook)(struct sudo_hook *hook));
1154 .Fn deregister_hooks
1155 function is called by the sudo front end
1156 to deregister any hooks the plugin has registered.
1157 If the plugin does not support hooks,
1158 .Li deregister_hooks
1159 should be set to the
1165 argument describes the version of the hooks API
1172 function should be used to deregister any
1173 hooks that were put in place by the
1176 If the plugin tries to deregister a hook that the front end does not support,
1178 will return an error.
1181 .Sx Hook function API
1182 section below for more information
1186 .Fn deregister_hooks
1187 function is only available starting
1188 with API version 1.2.
1191 front end doesn't support API
1192 version 1.2 or higher,
1193 .Li deregister_hooks
1197 .Em Policy Plugin Version Macros
1199 /* Plugin API version major/minor. */
1200 #define SUDO_API_VERSION_MAJOR 1
1201 #define SUDO_API_VERSION_MINOR 2
1202 #define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
1203 #define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR,\e
1204 SUDO_API_VERSION_MINOR)
1206 /* Getters and setters for API version */
1207 #define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
1208 #define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
1209 #define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \e
1210 *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
1212 #define SUDO_VERSION_SET_MINOR(vp, n) do { \e
1213 *(vp) = (*(vp) & 0xffff0000) | (n); \e
1219 #define SUDO_IO_PLUGIN 2
1220 unsigned int type; /* always SUDO_IO_PLUGIN */
1221 unsigned int version; /* always SUDO_API_VERSION */
1222 int (*open)(unsigned int version, sudo_conv_t conversation
1223 sudo_printf_t plugin_printf, char * const settings[],
1224 char * const user_info[], int argc, char * const argv[],
1225 char * const user_env[], char * const plugin_options[]);
1226 void (*close)(int exit_status, int error); /* wait status or error */
1227 int (*show_version)(int verbose);
1228 int (*log_ttyin)(const char *buf, unsigned int len);
1229 int (*log_ttyout)(const char *buf, unsigned int len);
1230 int (*log_stdin)(const char *buf, unsigned int len);
1231 int (*log_stdout)(const char *buf, unsigned int len);
1232 int (*log_stderr)(const char *buf, unsigned int len);
1233 void (*register_hooks)(int version,
1234 int (*register_hook)(struct sudo_hook *hook));
1235 void (*deregister_hooks)(int version,
1236 int (*deregister_hook)(struct sudo_hook *hook));
1240 When an I/O plugin is loaded,
1242 runs the command in a pseudo-tty.
1243 This makes it possible to log the input and output from the user's
1245 If any of the standard input, standard output or standard error do not
1246 correspond to a tty,
1248 will open a pipe to capture
1249 the I/O for logging before passing it on.
1251 The log_ttyin function receives the raw user input from the terminal
1252 device (note that this will include input even when echo is disabled,
1253 such as when a password is read).
1254 The log_ttyout function receives output from the pseudo-tty that is
1255 suitable for replaying the user's session at a later time.
1261 functions are only called if the standard input, standard output
1262 or standard error respectively correspond to something other than
1265 Any of the logging functions may be set to the
1267 pointer if no logging is to be performed.
1268 If the open function returns 0, no I/O will be sent to the plugin.
1270 The io_plugin struct has the following fields:
1275 field should always be set to
1276 .Dv SUDO_IO_PLUGIN .
1280 field should be set to
1281 .Dv SUDO_API_VERSION .
1285 to determine the API version the plugin was
1288 .Bd -literal -compact
1289 int (*open)(unsigned int version, sudo_conv_t conversation
1290 sudo_printf_t plugin_printf, char * const settings[],
1291 char * const user_info[], int argc, char * const argv[],
1292 char * const user_env[], char * const plugin_options[]);
1297 function is run before the
1302 functions are called.
1303 It is only called if the version is being requested or the
1306 returned successfully.
1307 It returns 1 on success, 0 on failure, \-1 if a general error occurred,
1308 or \-2 if there was a usage error.
1311 will print a usage message before it exits.
1312 If an error occurs, the plugin may optionally call the
1317 .Dv SUDO_CONF_ERROR_MSG
1319 additional error information to the user.
1321 The function arguments are as follows:
1324 The version passed in by
1326 allows the plugin to determine the
1327 major and minor version number of the plugin API supported by
1332 function that may be used by the
1334 function to display version information (see
1339 function may also be used to display additional error message to the user.
1342 function returns 0 on success and \-1 on failure.
1345 .Fn printf Ns No -style
1346 function that may be used by the
1348 function to display version information (see
1349 show_version below).
1352 function may also be used to display additional error message to the user.
1355 function returns number of characters printed on success and \-1 on failure.
1357 A vector of user-supplied
1359 settings in the form of
1362 The vector is terminated by a
1365 These settings correspond to flags the user specified when running
1367 As such, they will only be present when the corresponding flag has
1368 been specified on the command line.
1372 the plugin should split on the
1378 field will never include one
1384 .Sx Policy plugin API
1385 section for a list of all possible settings.
1387 A vector of information about the user running the command in the form of
1390 The vector is terminated by a
1396 the plugin should split on the
1402 field will never include one
1408 .Sx Policy plugin API
1409 section for a list of all possible strings.
1411 The number of elements in
1413 not counting the final
1418 .No non- Ns Dv NULL ,
1419 an argument vector describing a command the user
1420 wishes to run in the same form as what would be passed to the
1424 The user's environment in the form of a
1425 .Dv NULL Ns No -terminated
1432 the plugin should split on the
1438 field will never include one
1443 Any (non-comment) strings immediately after the plugin path are
1444 treated as arguments to the plugin.
1445 These arguments are split on a white space boundary and are passed to
1446 the plugin in the form of a
1447 .Dv NULL Ns No -terminated
1449 If no arguments were specified,
1457 parameter is only available starting with
1461 check the API version specified
1464 front end before using
1465 .Em plugin_options .
1466 Failure to do so may result in a crash.
1469 .Bd -literal -compact
1470 void (*close)(int exit_status, int error);
1475 function is called when the command being run by
1479 The function arguments are as follows:
1482 The command's exit status, as returned by the
1491 If the command could not be executed, this is set to the value of
1496 If the command was successfully executed, the value of
1501 .Bd -literal -compact
1502 int (*show_version)(int verbose);
1507 function is called by
1509 when the user specifies
1513 The plugin may display its version information to the user via the
1518 .Dv SUDO_CONV_INFO_MSG .
1519 If the user requests detailed version information, the verbose flag will be set.
1521 .Bd -literal -compact
1522 int (*log_ttyin)(const char *buf, unsigned int len);
1527 function is called whenever data can be read from
1528 the user but before it is passed to the running command.
1529 This allows the plugin to reject data if it chooses to (for instance
1530 if the input contains banned content).
1531 Returns 1 if the data should be passed to the command, 0 if the data
1532 is rejected (which will terminate the command) or \-1 if an error occurred.
1534 The function arguments are as follows:
1537 The buffer containing user input.
1544 .Bd -literal -compact
1545 int (*log_ttyout)(const char *buf, unsigned int len);
1550 function is called whenever data can be read from
1551 the command but before it is written to the user's terminal.
1552 This allows the plugin to reject data if it chooses to (for instance
1553 if the output contains banned content).
1554 Returns 1 if the data should be passed to the user, 0 if the data is rejected
1555 (which will terminate the command) or \-1 if an error occurred.
1557 The function arguments are as follows:
1560 The buffer containing command output.
1567 .Bd -literal -compact
1568 int (*log_stdin)(const char *buf, unsigned int len);
1573 function is only used if the standard input does
1574 not correspond to a tty device.
1575 It is called whenever data can be read from the standard input but
1576 before it is passed to the running command.
1577 This allows the plugin to reject data if it chooses to
1578 (for instance if the input contains banned content).
1579 Returns 1 if the data should be passed to the command, 0 if the data is
1580 rejected (which will terminate the command) or \-1 if an error occurred.
1582 The function arguments are as follows:
1585 The buffer containing user input.
1592 .Bd -literal -compact
1593 int (*log_stdout)(const char *buf, unsigned int len);
1598 function is only used if the standard output does not correspond
1600 It is called whenever data can be read from the command but before
1601 it is written to the standard output.
1602 This allows the plugin to reject data if it chooses to
1603 (for instance if the output contains banned content).
1604 Returns 1 if the data should be passed to the user, 0 if the data is
1605 rejected (which will terminate the command) or \-1 if an error occurred.
1607 The function arguments are as follows:
1610 The buffer containing command output.
1617 .Bd -literal -compact
1618 int (*log_stderr)(const char *buf, unsigned int len);
1623 function is only used if the standard error does
1624 not correspond to a tty device.
1625 It is called whenever data can be read from the command but before it
1626 is written to the standard error.
1627 This allows the plugin to reject data if it chooses to
1628 (for instance if the output contains banned content).
1629 Returns 1 if the data should be passed to the user, 0 if the data is
1630 rejected (which will terminate the command) or \-1 if an error occurred.
1632 The function arguments are as follows:
1635 The buffer containing command output.
1643 .Sx Policy plugin API
1644 section for a description of
1645 .Li register_hooks .
1646 .It deregister_hooks
1648 .Sx Policy plugin API
1649 section for a description of
1650 .Li deregister_hooks.
1653 .Em I/O Plugin Version Macros
1656 .Sx Policy plugin API .
1657 .Ss Hook function API
1658 Beginning with plugin API version 1.2, it is possible to install
1659 hooks for certain functions called by the
1663 Currently, the only supported hooks relate to the handling of
1664 environment variables.
1665 Hooks can be used to intercept attempts to get, set, or remove
1666 environment variables so that these changes can be reflected in
1667 the version of the environment that is used to execute a command.
1668 A future version of the API will support hooking internal
1670 front end functions as well.
1676 are described by the following structure:
1678 typedef int (*sudo_hook_fn_t)();
1683 sudo_hook_fn_t hook_fn;
1690 structure has the following fields:
1695 field should be set to
1696 .Dv SUDO_HOOK_VERSION .
1700 field may be one of the following supported hook types:
1702 .It Dv SUDO_HOOK_SETENV
1706 Any registered hooks will run before the C library implementation.
1710 be a function that matches the following typedef:
1712 typedef int (*sudo_hook_fn_setenv_t)(const char *name,
1713 const char *value, int overwrite, void *closure);
1716 If the registered hook does not match the typedef the results are
1718 .It Dv SUDO_HOOK_UNSETENV
1722 Any registered hooks will run before the C library implementation.
1726 be a function that matches the following typedef:
1728 typedef int (*sudo_hook_fn_unsetenv_t)(const char *name,
1731 .It Dv SUDO_HOOK_GETENV
1735 Any registered hooks will run before the C library implementation.
1739 be a function that matches the following typedef:
1741 typedef int (*sudo_hook_fn_getenv_t)(const char *name,
1742 char **value, void *closure);
1745 If the registered hook does not match the typedef the results are
1747 .It Dv SUDO_HOOK_PUTENV
1751 Any registered hooks will run before the C library implementation.
1755 be a function that matches the following typedef:
1757 typedef int (*sudo_hook_fn_putenv_t)(char *string,
1761 If the registered hook does not match the typedef the results are
1765 sudo_hook_fn_t hook_fn;
1769 field should be set to the plugin's hook implementation.
1770 The actual function arguments will vary depending on the
1778 .Li struct sudo_hook
1779 is passed as the last function parameter.
1780 This can be used to pass arbitrary data to the plugin's hook implementation.
1782 The function return value may be one of the following:
1784 .It Dv SUDO_HOOK_RET_ERROR
1785 The hook function encountered an error.
1786 .It Dv SUDO_HOOK_RET_NEXT
1787 The hook completed without error, go on to the next hook (including
1788 the native implementation if applicable).
1792 .Dv SUDO_HOOK_RET_NEXT
1793 if the specified variable was not found in the private copy of the environment.
1794 .It Dv SUDO_HOOK_RET_STOP
1795 The hook completed without error, stop processing hooks for this invocation.
1796 This can be used to replace the native implementation.
1799 hook that operates on a private copy of
1800 the environment but leaves
1806 Note that it is very easy to create an infinite loop when hooking
1807 C library functions.
1812 function may create a loop if the
1814 implementation calls
1816 to check the locale.
1817 To prevent this, you may wish to use a static variable in the hook
1818 function to guard against nested calls.
1821 static int in_progress = 0; /* avoid recursion */
1823 return SUDO_HOOK_RET_NEXT;
1827 return SUDO_HOOK_RET_STOP;
1830 .Em Hook API Version Macros
1832 /* Hook API version major/minor */
1833 #define SUDO_HOOK_VERSION_MAJOR 1
1834 #define SUDO_HOOK_VERSION_MINOR 0
1835 #define SUDO_HOOK_MKVERSION(x, y) ((x << 16) | y)
1836 #define SUDO_HOOK_VERSION SUDO_HOOK_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\e
1837 SUDO_HOOK_VERSION_MINOR)
1839 /* Getters and setters for hook API version */
1840 #define SUDO_HOOK_VERSION_GET_MAJOR(v) ((v) >> 16)
1841 #define SUDO_HOOK_VERSION_GET_MINOR(v) ((v) & 0xffff)
1842 #define SUDO_HOOK_VERSION_SET_MAJOR(vp, n) do { \e
1843 *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
1845 #define SUDO_HOOK_VERSION_SET_MINOR(vp, n) do { \e
1846 *(vp) = (*(vp) & 0xffff0000) | (n); \e
1849 .Ss Conversation API
1850 If the plugin needs to interact with the user, it may do so via the
1853 A plugin should not attempt to read directly from the standard input
1854 or the user's tty (neither of which are guaranteed to exist).
1855 The caller must include a trailing newline in
1857 if one is to be printed.
1860 .Fn printf Ns No -style
1861 function is also available that can be used to display informational
1862 or error messages to the user, which is usually more convenient for
1863 simple messages where no use input is required.
1865 struct sudo_conv_message {
1866 #define SUDO_CONV_PROMPT_ECHO_OFF 0x0001 /* do not echo user input */
1867 #define SUDO_CONV_PROMPT_ECHO_ON 0x0002 /* echo user input */
1868 #define SUDO_CONV_ERROR_MSG 0x0003 /* error message */
1869 #define SUDO_CONV_INFO_MSG 0x0004 /* informational message */
1870 #define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */
1871 #define SUDO_CONV_DEBUG_MSG 0x0006 /* debugging message */
1872 #define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */
1878 struct sudo_conv_reply {
1882 typedef int (*sudo_conv_t)(int num_msgs,
1883 const struct sudo_conv_message msgs[],
1884 struct sudo_conv_reply replies[]);
1886 typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
1892 .Fn printf Ns No -style
1893 functions are passed
1896 function when the plugin is initialized.
1900 function, the plugin must pass an array of
1901 .Li sudo_conv_message
1906 .Li struct sudo_conv_message
1908 .Li struct sudo_conv_reply
1910 each message in the conversation.
1911 The plugin is responsible for freeing the reply buffer filled in to the
1912 .Li struct sudo_conv_reply ,
1916 .Fn printf Ns No -style
1917 function uses the same underlying mechanism as the
1919 function but only supports
1920 .Dv SUDO_CONV_INFO_MSG ,
1921 .Dv SUDO_CONV_ERROR_MSG
1923 .Dv SUDO_CONV_DEBUG_MSG
1927 It can be more convenient than using the
1929 function if no user reply is needed and supports standard
1934 .Dv SUDO_CONV_INFO_MSG
1936 Dv SUDO_CONV_ERROR_MSG ,
1939 .Dv SUDO_CONV_DEBUG_MSG
1943 Instead, they are logged to the file specified in the
1945 statement (if any) in the
1946 .Pa @sysconfdir@/sudo.conf
1949 This allows a plugin to log debugging information and is intended
1950 to be used in conjunction with the
1954 See the sample plugin for an example of the
1957 .Ss Sudoers group plugin API
1960 module supports a plugin interface to allow non-Unix
1962 This can be used to query a group source other than the standard Unix
1964 A sample group plugin is bundled with
1966 that implements file-based lookups.
1967 Third party group plugins include a QAS AD plugin available from Quest Software.
1969 A group plugin must declare and populate a
1970 .Li sudoers_group_plugin
1971 struct in the global scope.
1972 This structure contains pointers to the functions that implement plugin
1973 initialization, cleanup and group lookup.
1975 struct sudoers_group_plugin {
1976 unsigned int version;
1977 int (*init)(int version, sudo_printf_t sudo_printf,
1978 char *const argv[]);
1979 void (*cleanup)(void);
1980 int (*query)(const char *user, const char *group,
1981 const struct passwd *pwd);
1986 .Li sudoers_group_plugin
1987 struct has the following fields:
1992 field should be set to GROUP_API_VERSION.
1996 to determine the API version the group plugin
1999 .Bd -literal -compact
2000 int (*init)(int version, sudo_printf_t plugin_printf,
2001 char *const argv[]);
2006 function is called after
2009 before any policy checks.
2010 It returns 1 on success, 0 on failure (or if the plugin is not configured),
2011 and \-1 if a error occurred.
2012 If an error occurs, the plugin may call the
2015 .Dv SUDO_CONF_ERROR_MSG
2016 to present additional error information
2019 The function arguments are as follows:
2022 The version passed in by
2024 allows the plugin to determine the
2025 major and minor version number of the group plugin API supported by
2029 .Fn printf Ns No -style
2030 function that may be used to display informational or error message to the user.
2031 Returns the number of characters printed on success and \-1 on failure.
2034 .Dv NULL Ns No -terminated
2035 array of arguments generated from the
2039 If no arguments were given,
2045 .Bd -literal -compact
2051 function is called when
2055 The plugin should free any memory it has allocated and close open file handles.
2057 .Bd -literal -compact
2058 int (*query)(const char *user, const char *group,
2059 const struct passwd *pwd);
2064 function is used to ask the group plugin whether
2069 The function arguments are as follows:
2072 The name of the user being looked up in the external group database.
2074 The name of the group being queried.
2076 The password database entry for
2082 present in the password database,
2089 .Em Group API Version Macros
2091 /* Sudoers group plugin version major/minor */
2092 #define GROUP_API_VERSION_MAJOR 1
2093 #define GROUP_API_VERSION_MINOR 0
2094 #define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \e
2095 GROUP_API_VERSION_MINOR)
2097 /* Getters and setters for group version */
2098 #define GROUP_API_VERSION_GET_MAJOR(v) ((v) >> 16)
2099 #define GROUP_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
2100 #define GROUP_API_VERSION_SET_MAJOR(vp, n) do { \e
2101 *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
2103 #define GROUP_API_VERSION_SET_MINOR(vp, n) do { \e
2104 *(vp) = (*(vp) & 0xffff0000) | (n); \e
2107 .Sh PLUGIN API CHANGELOG
2108 The following revisions have been made to the Sudo Plugin API.
2111 Initial API version.
2113 The I/O logging plugin's
2115 function was modified to take the
2117 list as an argument.
2119 The Policy and I/O logging plugins'
2121 functions are now passed
2122 a list of plugin options if any are specified in
2123 .Pa @sysconfdir@/sudo.conf .
2125 A simple hooks API has been introduced to allow plugins to hook in to the
2126 system's environment handling functions.
2130 Policy plugin function is now passed a pointer
2131 to the user environment which can be updated as needed.
2132 This can be used to merge in environment variables stored in the PAM
2133 handle before a command is run.
2136 .Xr sudoers @mansectform@ ,
2137 .Xr sudo @mansectsu@
2139 If you feel you have found a bug in
2141 please submit a bug report at http://www.sudo.ws/sudo/bugs/
2143 Limited free support is available via the sudo-users mailing list,
2144 see http://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
2145 search the archives.
2150 and any express or implied warranties, including, but not limited
2151 to, the implied warranties of merchantability and fitness for a
2152 particular purpose are disclaimed.
2153 See the LICENSE file distributed with
2155 or http://www.sudo.ws/sudo/license.html for complete details.