Imported Upstream version 1.8.7
[debian/sudo] / doc / sudo_plugin.mdoc.in
1 .\"
2 .\" Copyright (c) 2009-2013 Todd C. Miller <Todd.Miller@courtesan.com>
3 .\"
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.
7 .\"
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.
16 .\"
17 .Dd March 5, 2013
18 .Dt SUDO_PLUGIN @mansectform@
19 .Os Sudo @PACKAGE_VERSION@
20 .Sh NAME
21 .Nm sudo_plugin
22 .Nd Sudo Plugin API
23 .Sh DESCRIPTION
24 Starting with version 1.8,
25 .Nm sudo
26 supports a plugin API
27 for policy and session logging.
28 By default, the
29 .Nm sudoers
30 policy plugin and an associated I/O logging plugin are used.
31 Via the plugin API,
32 .Nm sudo
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 in the
36 .Xr sudo.conf @mansectform@
37 file.
38 .Pp
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.
44 .Pp
45 The plugin API is defined by the
46 .Li sudo_plugin.h
47 header file.
48 .Ss Policy plugin API
49 A policy plugin must declare and populate a
50 .Li policy_plugin
51 struct in the global scope.
52 This structure contains pointers to the functions that implement the
53 .Nm sudo
54 policy checks.
55 The name of the symbol should be specified in
56 .Xr sudo.conf @mansectform@
57 along with a path to the plugin so that
58 .Nm sudo
59 can load it.
60 .Bd -literal
61 struct policy_plugin {
62 #define SUDO_POLICY_PLUGIN     1
63     unsigned int type; /* always SUDO_POLICY_PLUGIN */
64     unsigned int version; /* always SUDO_API_VERSION */
65     int (*open)(unsigned int version, sudo_conv_t conversation,
66                 sudo_printf_t plugin_printf, char * const settings[],
67                 char * const user_info[], char * const user_env[],
68                 char * const plugin_options[]);
69     void (*close)(int exit_status, int error);
70     int (*show_version)(int verbose);
71     int (*check_policy)(int argc, char * const argv[],
72                         char *env_add[], char **command_info[],
73                         char **argv_out[], char **user_env_out[]);
74     int (*list)(int argc, char * const argv[], int verbose,
75                 const char *list_user);
76     int (*validate)(void);
77     void (*invalidate)(int remove);
78     int (*init_session)(struct passwd *pwd, char **user_env[]);
79     void (*register_hooks)(int version,
80        int (*register_hook)(struct sudo_hook *hook));
81     void (*deregister_hooks)(int version,
82        int (*deregister_hook)(struct sudo_hook *hook));
83 };
84 .Ed
85 .Pp
86 The policy_plugin struct has the following fields:
87 .Bl -tag -width 4n
88 .It type
89 The
90 .Li type
91 field should always be set to SUDO_POLICY_PLUGIN.
92 .It version
93 The
94 .Li version
95 field should be set to
96 .Dv SUDO_API_VERSION .
97 .Pp
98 This allows
99 .Nm sudo
100 to determine the API version the plugin was
101 built against.
102 .It open
103 .Bd -literal -compact
104 int (*open)(unsigned int version, sudo_conv_t conversation,
105             sudo_printf_t plugin_printf, char * const settings[],
106             char * const user_info[], char * const user_env[],
107             char * const plugin_options[]);
108 .Ed
109 .Pp
110 Returns 1 on success, 0 on failure, \-1 if a general error occurred,
111 or \-2 if there was a usage error.
112 In the latter case,
113 .Nm sudo
114 will print a usage message before it exits.
115 If an error occurs, the plugin may optionally call the
116 .Fn conversation
117 or
118 .Fn plugin_printf
119 function with
120 .Dv SUDO_CONF_ERROR_MSG
121 to present additional error information to the user.
122 .Pp
123 The function arguments are as follows:
124 .Bl -tag -width 4n
125 .It version
126 The version passed in by
127 .Nm sudo
128 allows the plugin to determine the
129 major and minor version number of the plugin API supported by
130 .Nm sudo .
131 .It conversation
132 A pointer to the
133 .Fn conversation
134 function that can be used by the plugin to interact with the user (see below).
135 Returns 0 on success and \-1 on failure.
136 .It plugin_printf
137 A pointer to a
138 .Fn printf Ns No -style
139 function that may be used to display informational or error messages
140 (see below).
141 Returns the number of characters printed on success and \-1 on failure.
142 .It settings
143 A vector of user-supplied
144 .Nm sudo
145 settings in the form of
146 .Dq name=value
147 strings.
148 The vector is terminated by a
149 .Dv NULL
150 pointer.
151 These settings correspond to flags the user specified when running
152 .Nm sudo .
153 As such, they will only be present when the corresponding flag has
154 been specified on the command line.
155 .Pp
156 When parsing
157 .Em settings ,
158 the plugin should split on the
159 .Sy first
160 equal sign
161 .Pq Ql =
162 since the
163 .Em name
164 field will never include one
165 itself but the
166 .Em value
167 might.
168 .Bl -tag -width 4n
169 .It bsdauth_type=string
170 Authentication type, if specified by the
171 .Fl a
172 flag, to use on
173 systems where BSD authentication is supported.
174 .It closefrom=number
175 If specified, the user has requested via the
176 .Fl C
177 flag that
178 .Nm sudo
179 close all files descriptors with a value of
180 .Em number
181 or higher.
182 The plugin may optionally pass this, or another value, back in the
183 .Em command_info
184 list.
185 .It debug_flags=string
186 A comma-separated list of debug flags that correspond to
187 .Nm sudo Ns No 's
188 .Li Debug
189 entry in
190 .Xr sudo.conf @mansectform@ ,
191 if there is one.
192 The flags are passed to the plugin as they appear in
193 .Xr sudo.conf @mansectform@ .
194 The syntax used by
195 .Nm sudo
196 and the
197 .Nm sudoers
198 plugin is
199 .Em subsystem Ns No @ Ns Em priority
200 but the plugin is free to use a different
201 format so long as it does not include a comma
202 .Pq Ql ,\& .
203 There is not currently a way to specify a set of debug flags specific
204 to the plugin--the flags are shared by
205 .Nm sudo
206 and the plugin.
207 .It debug_level=number
208 This setting has been deprecated in favor of
209 .Em debug_flags .
210 .It ignore_ticket=bool
211 Set to true if the user specified the
212 .Fl k
213 flag along with a
214 command, indicating that the user wishes to ignore any cached
215 authentication credentials.
216 .Em implied_shell
217 to true.
218 This allows
219 .Nm sudo
220 with no arguments
221 to be used similarly to
222 .Xr su 1 .
223 If the plugin does not to support this usage, it may return a value of \-2
224 from the
225 .Fn check_policy
226 function, which will cause
227 .Nm sudo
228 to print a usage message and
229 exit.
230 .It implied_shell=bool
231 If the user does not specify a program on the command line,
232 .Nm sudo
233 will pass the plugin the path to the user's shell and set
234 .It login_class=string
235 BSD login class to use when setting resource limits and nice value,
236 if specified by the
237 .Fl c
238 flag.
239 .It login_shell=bool
240 Set to true if the user specified the
241 .Fl i
242 flag, indicating that
243 the user wishes to run a login shell.
244 .It max_groups=int
245 The maximum number of groups a user may belong to.
246 This will only be present if there is a corresponding setting in
247 .Xr sudo.conf @mansectform@ .
248 .It network_addrs=list
249 A space-separated list of IP network addresses and netmasks in the
250 form
251 .Dq addr/netmask ,
252 e.g.\&
253 .Dq 192.168.1.2/255.255.255.0 .
254 The address and netmask pairs may be either IPv4 or IPv6, depending on
255 what the operating system supports.
256 If the address contains a colon
257 .Pq Ql :\& ,
258 it is an IPv6 address, else it is IPv4.
259 .It noninteractive=bool
260 Set to true if the user specified the
261 .Fl n
262 flag, indicating that
263 .Nm sudo
264 should operate in non-interactive mode.
265 The plugin may reject a command run in non-interactive mode if user
266 interaction is required.
267 .It plugin_dir=string
268 The default plugin directory used by the
269 .Nm sudo
270 front end.
271 This is the default directory set at compile time and may not
272 correspond to the directory the running plugin was loaded from.
273 It may be used by a plugin to locate support files.
274 .It preserve_environment=bool
275 Set to true if the user specified the
276 .Fl E
277 flag, indicating that
278 the user wishes to preserve the environment.
279 .It preserve_groups=bool
280 Set to true if the user specified the
281 .Fl P
282 flag, indicating that
283 the user wishes to preserve the group vector instead of setting it
284 based on the runas user.
285 .It progname=string
286 The command name that sudo was run as, typically
287 .Dq sudo
288 or
289 .Dq sudoedit .
290 .It prompt=string
291 The prompt to use when requesting a password, if specified via
292 the
293 .Fl p
294 flag.
295 .It run_shell=bool
296 Set to true if the user specified the
297 .Fl s
298 flag, indicating that
299 the user wishes to run a shell.
300 .It runas_group=string
301 The group name or gid to to run the command as, if specified via
302 the
303 .Fl g
304 flag.
305 .It runas_user=string
306 The user name or uid to to run the command as, if specified via the
307 .Fl u
308 flag.
309 .It selinux_role=string
310 SELinux role to use when executing the command, if specified by
311 the
312 .Fl r
313 flag.
314 .It selinux_type=string
315 SELinux type to use when executing the command, if specified by
316 the
317 .Fl t
318 flag.
319 .It set_home=bool
320 Set to true if the user specified the
321 .Fl H
322 flag.
323 If true, set the
324 .Li HOME
325 environment variable to the target user's home directory.
326 .It sudoedit=bool
327 Set to true when the
328 .Fl e
329 flag is is specified or if invoked as
330 .Nm sudoedit .
331 The plugin shall substitute an editor into
332 .Em argv
333 in the
334 .Fn check_policy
335 function or return \-2 with a usage error
336 if the plugin does not support
337 .Em sudoedit .
338 For more information, see the
339 .Em check_policy
340 section.
341 .El
342 .Pp
343 Additional settings may be added in the future so the plugin should
344 silently ignore settings that it does not recognize.
345 .It user_info
346 A vector of information about the user running the command in the form of
347 .Dq name=value
348 strings.
349 The vector is terminated by a
350 .Dv NULL
351 pointer.
352 .Pp
353 When parsing
354 .Em user_info ,
355 the plugin should split on the
356 .Sy first
357 equal sign
358 .Pq Ql =
359 since the
360 .Em name
361 field will never include one
362 itself but the
363 .Em value
364 might.
365 .Bl -tag -width 4n
366 .It cols=int
367 The number of columns the user's terminal supports.
368 If there is no terminal device available, a default value of 80 is used.
369 .It cwd=string
370 The user's current working directory.
371 .It egid=gid_t
372 The effective group ID of the user invoking
373 .Nm sudo .
374 .It euid=uid_t
375 The effective user ID of the user invoking
376 .Nm sudo .
377 .It gid=gid_t
378 The real group ID of the user invoking
379 .Nm sudo .
380 .It groups=list
381 The user's supplementary group list formatted as a string of
382 comma-separated group IDs.
383 .It host=string
384 The local machine's hostname as returned by the
385 .Xr gethostname 2
386 system call.
387 .It lines=int
388 The number of lines the user's terminal supports.
389 If there is
390 no terminal device available, a default value of 24 is used.
391 .It pgid=int
392 The ID of the process group that the running
393 .Nm sudo
394 process is a member of.
395 Only available starting with API version 1.2
396 .It pid=int
397 The process ID of the running
398 .Nm sudo
399 process.
400 Only available starting with API version 1.2
401 .It plugin_options
402 Any (non-comment) strings immediately after the plugin path are
403 passed as arguments to the plugin.
404 These arguments are split on a white space boundary and are passed to
405 the plugin in the form of a
406 .Dv NULL Ns No -terminated
407 array of strings.
408 If no arguments were
409 specified,
410 .Em plugin_options
411 will be the
412 .Dv NULL
413 pointer.
414 .Pp
415 NOTE: the
416 .Em plugin_options
417 parameter is only available starting with
418 API version 1.2.
419 A plugin
420 .Sy must
421 check the API version specified
422 by the
423 .Nm sudo
424 front end before using
425 .Em plugin_options .
426 Failure to do so may result in a crash.
427 .It ppid=int
428 The parent process ID of the running
429 .Nm sudo
430 process.
431 Only available starting with API version 1.2
432 .It sid=int
433 The session ID of the running
434 .Nm sudo
435 process or 0 if
436 .Nm sudo
437 is not part of a POSIX job control session.
438 Only available starting with API version 1.2
439 .It tcpgid=int
440 The ID of the foreground process group associated with the terminal
441 device associated with the
442 .Nm sudo
443 process or \-1 if there is no
444 terminal present.
445 Only available starting with API version 1.2
446 .It tty=string
447 The path to the user's terminal device.
448 If the user has no terminal device associated with the session,
449 the value will be empty, as in
450 .Dq Li tty= .
451 .It uid=uid_t
452 The real user ID of the user invoking
453 .Nm sudo .
454 .It user=string
455 The name of the user invoking
456 .Nm sudo .
457 .El
458 .It user_env
459 The user's environment in the form of a
460 .Dv NULL Ns No -terminated vector of
461 .Dq name=value
462 strings.
463 .Pp
464 When parsing
465 .Em user_env ,
466 the plugin should split on the
467 .Sy first
468 equal sign
469 .Pq Ql =
470 since the
471 .Em name
472 field will never include one
473 itself but the
474 .Em value
475 might.
476 .El
477 .It close
478 .Bd -literal -compact
479 void (*close)(int exit_status, int error);
480 .Ed
481 .Pp
482 The
483 .Fn close
484 function is called when the command being run by
485 .Nm sudo
486 finishes.
487 .Pp
488 The function arguments are as follows:
489 .Bl -tag -width 4n
490 .It exit_status
491 The command's exit status, as returned by the
492 .Xr wait 2
493 system call.
494 The value of
495 .Li exit_status
496 is undefined if
497 .Li error
498 is non-zero.
499 .It error
500 If the command could not be executed, this is set to the value of
501 .Li errno
502 set by the
503 .Xr execve 2
504 system call.
505 The plugin is responsible for displaying error information via the
506 .Fn conversation
507 or
508 .Fn plugin_printf
509 function.
510 If the command was successfully executed, the value of
511 .Li error
512 is 0.
513 .El
514 .Pp
515 If no
516 .Fn close
517 function is defined, no I/O logging plugins are loaded,
518 and neither the
519 .Em timeout
520 not
521 .Em use_pty
522 options are set in the
523 .Li command_info
524 list, the
525 .Nm sudo
526 front end may execute the command directly instead of running
527 it as a child process.
528 .It show_version
529 .Bd -literal -compact
530 int (*show_version)(int verbose);
531 .Ed
532 .Pp
533 The
534 .Fn show_version
535 function is called by
536 .Nm sudo
537 when the user specifies
538 the
539 .Fl V
540 option.
541 The plugin may display its version information to the user via the
542 .Fn conversation
543 or
544 .Fn plugin_printf
545 function using
546 .Dv SUDO_CONV_INFO_MSG .
547 If the user requests detailed version information, the verbose flag will be set.
548 .It check_policy
549 .Bd -literal -compact
550 int (*check_policy)(int argc, char * const argv[]
551                     char *env_add[], char **command_info[],
552                     char **argv_out[], char **user_env_out[]);
553 .Ed
554 .Pp
555 The
556 .Fn check_policy
557 function is called by
558 .Nm sudo
559 to determine
560 whether the user is allowed to run the specified commands.
561 .Pp
562 If the
563 .Em sudoedit
564 option was enabled in the
565 .Em settings
566 array
567 passed to the
568 .Fn open
569 function, the user has requested
570 .Em sudoedit
571 mode.
572 .Em sudoedit
573 is a mechanism for editing one or more files
574 where an editor is run with the user's credentials instead of with
575 elevated privileges.
576 .Nm sudo
577 achieves this by creating user-writable
578 temporary copies of the files to be edited and then overwriting the
579 originals with the temporary copies after editing is complete.
580 If the plugin supports
581 .Em sudoedit ,
582 it should choose the editor to be used, potentially from a variable
583 in the user's environment, such as
584 .Li EDITOR ,
585 and include it in
586 .Em argv_out
587 (note that environment
588 variables may include command line flags).
589 The files to be edited should be copied from
590 .Em argv
591 into
592 .Em argv_out ,
593 separated from the
594 editor and its arguments by a
595 .Dq Li --
596 element.
597 The
598 .Dq Li --
599 will
600 be removed by
601 .Nm sudo
602 before the editor is executed.
603 The plugin should also set
604 .Em sudoedit=true
605 in the
606 .Em command_info
607 list.
608 .Pp
609 The
610 .Fn check_policy
611 function returns 1 if the command is allowed,
612 0 if not allowed, \-1 for a general error, or \-2 for a usage error
613 or if
614 .Em sudoedit
615 was specified but is unsupported by the plugin.
616 In the latter case,
617 .Nm sudo
618 will print a usage message before it
619 exits.
620 If an error occurs, the plugin may optionally call the
621 .Fn conversation
622 or
623 .Fn plugin_printf
624 function with
625 .Dv SUDO_CONF_ERROR_MSG
626 to present additional error information to the user.
627 .Pp
628 The function arguments are as follows:
629 .Bl -tag -width 4n
630 .It argc
631 The number of elements in
632 .Em argv ,
633 not counting the final
634 .Dv NULL
635 pointer.
636 .It argv
637 The argument vector describing the command the user wishes to run,
638 in the same form as what would be passed to the
639 .Xr execve 2
640 system call.
641 The vector is terminated by a
642 .Dv NULL
643 pointer.
644 .It env_add
645 Additional environment variables specified by the user on the command
646 line in the form of a
647 .Dv NULL Ns No -terminated
648 vector of
649 .Dq name=value
650 strings.
651 The plugin may reject the command if one or more variables
652 are not allowed to be set, or it may silently ignore such variables.
653 .Pp
654 When parsing
655 .Em env_add ,
656 the plugin should split on the
657 .Sy first
658 equal sign
659 .Pq Ql =
660 since the
661 .Em name
662 field will never include one
663 itself but the
664 .Em value
665 might.
666 .It command_info
667 Information about the command being run in the form of
668 .Dq name=value
669 strings.
670 These values are used by
671 .Nm sudo
672 to set the execution
673 environment when running a command.
674 The plugin is responsible for creating and populating the vector,
675 which must be terminated with a
676 .Dv NULL
677 pointer.
678 The following values are recognized by
679 .Nm sudo :
680 .Bl -tag -width 4n
681 .It chroot=string
682 The root directory to use when running the command.
683 .It closefrom=number
684 If specified,
685 .Nm sudo
686 will close all files descriptors with a value
687 of
688 .Em number
689 or higher.
690 .It command=string
691 Fully qualified path to the command to be executed.
692 .It cwd=string
693 The current working directory to change to when executing the command.
694 .It exec_background=bool
695 By default,
696 .Nm sudo
697 runs a command as the foreground process as long as
698 .Nm sudo
699 itself is running in the foreground.
700 When
701 .Em exec_background
702 is enabled and the command is being run in a pty (due to I/O logging
703 or the
704 .Em use_pty
705 setting), the command will be run as a background process.
706 Attempts to read from the controlling terminal (or to change terminal
707 settings) will result in the command being suspended with the
708 .Dv SIGTTIN
709 signal (or
710 .Dv SIGTTOU
711 in the case of terminal settings).
712 If this happens when
713 .Nm sudo
714 is a foreground process, the command will be granted the controlling terminal
715 and resumed in the foreground with no user intervention required.
716 The advantage of initially running the command in the background is that
717 .Nm sudo
718 need not read from the terminal unless the command explicitly requests it.
719 Otherwise, any terminal input must be passed to the command, whether it
720 has required it or not (the kernel buffers terminals so it is not possible
721 to tell whether the command really wants the input).
722 This is different from historic
723 .Em sudo
724 behavior or when the command is not being run in a pty.
725 .Pp
726 For this to work seamlessly, the operating system must support the
727 automatic restarting of system calls.
728 Unfortunately, not all operating systems do this by default,
729 and even those that do may have bugs.
730 For example, Mac OS X fails to restart the
731 .Fn tcgetattr
732 and
733 .Fn tcsetattr
734 system calls (this is a bug in Mac OS X).
735 Furthermore, because this behavior depends on the command stopping with the
736 .Dv SIGTTIN
737 or
738 .Dv SIGTTOU
739 signals, programs that catch these signals and suspend themselves
740 with a different signal (usually
741 .Dv SIGTOP )
742 will not be automatically foregrounded.
743 Some versions of the linux
744 .Xr su 1
745 command behave this way.
746 Because of this, a plugin should not set
747 .Em exec_background
748 unless it is explicitly enabled by the administrator and there should
749 be a way to enabled or disable it on a per-command basis.
750 .Pp
751 This setting has no effect unless I/O logging is enabled or
752 .Em use_pty
753 is enabled.
754 .It iolog_compress=bool
755 Set to true if the I/O logging plugins, if any, should compress the
756 log data.
757 This is a hint to the I/O logging plugin which may choose to ignore it.
758 .It iolog_path=string
759 Fully qualified path to the file or directory in which I/O log is
760 to be stored.
761 This is a hint to the I/O logging plugin which may choose to ignore it.
762 If no I/O logging plugin is loaded, this setting has no effect.
763 .It iolog_stdin=bool
764 Set to true if the I/O logging plugins, if any, should log the
765 standard input if it is not connected to a terminal device.
766 This is a hint to the I/O logging plugin which may choose to ignore it.
767 .It iolog_stdout=bool
768 Set to true if the I/O logging plugins, if any, should log the
769 standard output if it is not connected to a terminal device.
770 This is a hint to the I/O logging plugin which may choose to ignore it.
771 .It iolog_stderr=bool
772 Set to true if the I/O logging plugins, if any, should log the
773 standard error if it is not connected to a terminal device.
774 This is a hint to the I/O logging plugin which may choose to ignore it.
775 .It iolog_ttyin=bool
776 Set to true if the I/O logging plugins, if any, should log all
777 terminal input.
778 This only includes input typed by the user and not from a pipe or
779 redirected from a file.
780 This is a hint to the I/O logging plugin which may choose to ignore it.
781 .It iolog_ttyout=bool
782 Set to true if the I/O logging plugins, if any, should log all
783 terminal output.
784 This only includes output to the screen, not output to a pipe or file.
785 This is a hint to the I/O logging plugin which may choose to ignore it.
786 .It login_class=string
787 BSD login class to use when setting resource limits and nice value
788 (optional).
789 This option is only set on systems that support login classes.
790 .It nice=int
791 Nice value (priority) to use when executing the command.
792 The nice value, if specified, overrides the priority associated with the
793 .Em login_class
794 on BSD systems.
795 .It noexec=bool
796 If set, prevent the command from executing other programs.
797 .It preserve_groups=bool
798 If set,
799 .Nm sudo
800 will preserve the user's group vector instead of
801 initializing the group vector based on
802 .Li runas_user .
803 .It runas_egid=gid
804 Effective group ID to run the command as.
805 If not specified, the value of
806 .Em runas_gid
807 is used.
808 .It runas_euid=uid
809 Effective user ID to run the command as.
810 If not specified, the value of
811 .Em runas_uid
812 is used.
813 .It runas_gid=gid
814 Group ID to run the command as.
815 .It runas_groups=list
816 The supplementary group vector to use for the command in the form
817 of a comma-separated list of group IDs.
818 If
819 .Em preserve_groups
820 is set, this option is ignored.
821 .It runas_uid=uid
822 User ID to run the command as.
823 .It selinux_role=string
824 SELinux role to use when executing the command.
825 .It selinux_type=string
826 SELinux type to use when executing the command.
827 .It set_utmp=bool
828 Create a utmp (or utmpx) entry when a pseudo-tty is allocated.
829 By default, the new entry will be a copy of the user's existing utmp
830 entry (if any), with the tty, time, type and pid fields updated.
831 .It sudoedit=bool
832 Set to true when in
833 .Em sudoedit
834 mode.
835 The plugin may enable
836 .Em sudoedit
837 mode even if
838 .Nm sudo
839 was not invoked as
840 .Nm sudoedit .
841 This allows the plugin to perform command substitution and transparently
842 enable
843 .Em sudoedit
844 when the user attempts to run an editor.
845 .It timeout=int
846 Command timeout.
847 If non-zero then when the timeout expires the command will be killed.
848 .It umask=octal
849 The file creation mask to use when executing the command.
850 .It use_pty=bool
851 Allocate a pseudo-tty to run the command in, regardless of whether
852 or not I/O logging is in use.
853 By default,
854 .Nm sudo
855 will only run
856 the command in a pty when an I/O log plugin is loaded.
857 .It utmp_user=string
858 User name to use when constructing a new utmp (or utmpx) entry when
859 .Em set_utmp
860 is enabled.
861 This option can be used to set the user field in the utmp entry to
862 the user the command runs as rather than the invoking user.
863 If not set,
864 .Nm sudo
865 will base the new entry on
866 the invoking user's existing entry.
867 .El
868 .Pp
869 Unsupported values will be ignored.
870 .It argv_out
871 The
872 .Dv NULL Ns No -terminated
873 argument vector to pass to the
874 .Xr execve 2
875 system call when executing the command.
876 The plugin is responsible for allocating and populating the vector.
877 .It user_env_out
878 The
879 .Dv NULL Ns No -terminated
880 environment vector to use when executing the command.
881 The plugin is responsible for allocating and populating the vector.
882 .El
883 .It list
884 .Bd -literal -compact
885 int (*list)(int verbose, const char *list_user,
886             int argc, char * const argv[]);
887 .Ed
888 .Pp
889 List available privileges for the invoking user.
890 Returns 1 on success, 0 on failure and \-1 on error.
891 On error, the plugin may optionally call the
892 .Fn conversation
893 or
894 .Fn plugin_printf
895 function with
896 .Dv SUDO_CONF_ERROR_MSG
897 to present additional error information to
898 the user.
899 .Pp
900 Privileges should be output via the
901 .Fn conversation
902 or
903 .Fn plugin_printf
904 function using
905 .Dv SUDO_CONV_INFO_MSG ,
906 .Bl -tag -width 4n
907 .It verbose
908 Flag indicating whether to list in verbose mode or not.
909 .It list_user
910 The name of a different user to list privileges for if the policy
911 allows it.
912 If
913 .Dv NULL ,
914 the plugin should list the privileges of the invoking user.
915 .It argc
916 The number of elements in
917 .Em argv ,
918 not counting the final
919 .Dv NULL
920 pointer.
921 .It argv
922 If
923 .No non- Ns Dv NULL ,
924 an argument vector describing a command the user
925 wishes to check against the policy in the same form as what would
926 be passed to the
927 .Xr execve 2
928 system call.
929 If the command is permitted by the policy, the fully-qualified path
930 to the command should be displayed along with any command line arguments.
931 .El
932 .It validate
933 .Bd -literal -compact
934 int (*validate)(void);
935 .Ed
936 .Pp
937 The
938 .Fn validate
939 function is called when
940 .Nm sudo
941 is run with the
942 .Fl v
943 flag.
944 For policy plugins such as
945 .Nm sudoers
946 that cache
947 authentication credentials, this function will validate and cache
948 the credentials.
949 .Pp
950 The
951 .Fn validate
952 function should be
953 .Dv NULL
954 if the plugin does not support credential caching.
955 .Pp
956 Returns 1 on success, 0 on failure and \-1 on error.
957 On error, the plugin may optionally call the
958 .Fn conversation
959 or
960 .Fn plugin_printf
961 function with
962 .Dv SUDO_CONF_ERROR_MSG
963 to present additional
964 error information to the user.
965 .It invalidate
966 .Bd -literal -compact
967 void (*invalidate)(int remove);
968 .Ed
969 .Pp
970 The
971 .Fn invalidate
972 function is called when
973 .Nm sudo
974 is called with
975 the
976 .Fl k
977 or
978 .Fl K
979 flag.
980 For policy plugins such as
981 .Nm sudoers
982 that
983 cache authentication credentials, this function will invalidate the
984 credentials.
985 If the
986 .Em remove
987 flag is set, the plugin may remove
988 the credentials instead of simply invalidating them.
989 .Pp
990 The
991 .Fn invalidate
992 function should be
993 .Dv NULL
994 if the plugin does not support credential caching.
995 .It init_session
996 .Bd -literal -compact
997 int (*init_session)(struct passwd *pwd, char **user_envp[);
998 .Ed
999 .Pp
1000 The
1001 .Fn init_session
1002 function is called before
1003 .Nm sudo
1004 sets up the
1005 execution environment for the command.
1006 It is run in the parent
1007 .Nm sudo
1008 process and before any uid or gid changes.
1009 This can be used to perform session setup that is not supported by
1010 .Em command_info ,
1011 such as opening the PAM session.
1012 The
1013 .Fn close
1014 function can be
1015 used to tear down the session that was opened by
1016 .Li init_session .
1017 .Pp
1018 The
1019 .Em pwd
1020 argument points to a passwd struct for the user the
1021 command will be run as if the uid the command will run as was found
1022 in the password database, otherwise it will be
1023 .Dv NULL .
1024 .Pp
1025 The
1026 .Em user_env
1027 argument points to the environment the command will
1028 run in, in the form of a
1029 .Dv NULL Ns No -terminated
1030 vector of
1031 .Dq name=value
1032 strings.
1033 This is the same string passed back to the front end via
1034 the Policy Plugin's
1035 .Em user_env_out
1036 parameter.
1037 If the
1038 .Fn init_session
1039 function needs to modify the user environment, it should update the
1040 pointer stored in
1041 .Em user_env .
1042 The expected use case is to merge the contents of the PAM environment
1043 (if any) with the contents of
1044 .Em user_env .
1045 NOTE: the
1046 .Em user_env
1047 parameter is only available
1048 starting with API version 1.2.
1049 A plugin
1050 .Sy must
1051 check the API
1052 version specified by the
1053 .Nm sudo
1054 front end before using
1055 .Em user_env .
1056 Failure to do so may result in a crash.
1057 .Pp
1058 Returns 1 on success, 0 on failure and \-1 on error.
1059 On error, the plugin may optionally call the
1060 .Fn conversation
1061 or
1062 .Fn plugin_printf
1063 function with
1064 .Dv SUDO_CONF_ERROR_MSG
1065 to present additional
1066 error information to the user.
1067 .It register_hooks
1068 .Bd -literal -compact
1069 void (*register_hooks)(int version,
1070    int (*register_hook)(struct sudo_hook *hook));
1071 .Ed
1072 .Pp
1073 The
1074 .Fn register_hooks
1075 function is called by the sudo front end to
1076 register any hooks the plugin needs.
1077 If the plugin does not support hooks,
1078 .Li register_hooks
1079 should be set to the
1080 .Dv NULL
1081 pointer.
1082 .Pp
1083 The
1084 .Em version
1085 argument describes the version of the hooks API
1086 supported by the
1087 .Nm sudo
1088 front end.
1089 .Pp
1090 The
1091 .Fn register_hook
1092 function should be used to register any supported
1093 hooks the plugin needs.
1094 It returns 0 on success, 1 if the hook type is not supported and \-1
1095 if the major version in
1096 .Li struct hook
1097 does not match the front end's major hook API version.
1098 .Pp
1099 See the
1100 .Sx Hook function API
1101 section below for more information
1102 about hooks.
1103 .Pp
1104 NOTE: the
1105 .Fn register_hooks
1106 function is only available starting
1107 with API version 1.2.
1108 If the
1109 .Nm sudo
1110 front end doesn't support API
1111 version 1.2 or higher,
1112 .Li register_hooks
1113 will not be called.
1114 .It deregister_hooks
1115 .Bd -literal -compact
1116 void (*deregister_hooks)(int version,
1117    int (*deregister_hook)(struct sudo_hook *hook));
1118 .Ed
1119 .Pp
1120 The
1121 .Fn deregister_hooks
1122 function is called by the sudo front end
1123 to deregister any hooks the plugin has registered.
1124 If the plugin does not support hooks,
1125 .Li deregister_hooks
1126 should be set to the
1127 .Dv NULL
1128 pointer.
1129 .Pp
1130 The
1131 .Em version
1132 argument describes the version of the hooks API
1133 supported by the
1134 .Nm sudo
1135 front end.
1136 .Pp
1137 The
1138 .Fn deregister_hook
1139 function should be used to deregister any
1140 hooks that were put in place by the
1141 .Fn register_hook
1142 function.
1143 If the plugin tries to deregister a hook that the front end does not support,
1144 .Li deregister_hook
1145 will return an error.
1146 .Pp
1147 See the
1148 .Sx Hook function API
1149 section below for more information
1150 about hooks.
1151 .Pp
1152 NOTE: the
1153 .Fn deregister_hooks
1154 function is only available starting
1155 with API version 1.2.
1156 If the
1157 .Nm sudo
1158 front end doesn't support API
1159 version 1.2 or higher,
1160 .Li deregister_hooks
1161 will not be called.
1162 .El
1163 .Pp
1164 .Em Policy Plugin Version Macros
1165 .Bd -literal
1166 /* Plugin API version major/minor. */
1167 #define SUDO_API_VERSION_MAJOR 1
1168 #define SUDO_API_VERSION_MINOR 2
1169 #define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
1170 #define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR,\e
1171                                             SUDO_API_VERSION_MINOR)
1172
1173 /* Getters and setters for API version */
1174 #define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
1175 #define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
1176 #define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \e
1177     *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
1178 } while(0)
1179 #define SUDO_VERSION_SET_MINOR(vp, n) do { \e
1180     *(vp) = (*(vp) & 0xffff0000) | (n); \e
1181 } while(0)
1182 .Ed
1183 .Ss I/O plugin API
1184 .Bd -literal
1185 struct io_plugin {
1186 #define SUDO_IO_PLUGIN 2
1187     unsigned int type; /* always SUDO_IO_PLUGIN */
1188     unsigned int version; /* always SUDO_API_VERSION */
1189     int (*open)(unsigned int version, sudo_conv_t conversation,
1190                 sudo_printf_t plugin_printf, char * const settings[],
1191                 char * const user_info[], char * const command_info[],
1192                 int argc, char * const argv[], char * const user_env[],
1193                 char * const plugin_options[]);
1194     void (*close)(int exit_status, int error); /* wait status or error */
1195     int (*show_version)(int verbose);
1196     int (*log_ttyin)(const char *buf, unsigned int len);
1197     int (*log_ttyout)(const char *buf, unsigned int len);
1198     int (*log_stdin)(const char *buf, unsigned int len);
1199     int (*log_stdout)(const char *buf, unsigned int len);
1200     int (*log_stderr)(const char *buf, unsigned int len);
1201     void (*register_hooks)(int version,
1202        int (*register_hook)(struct sudo_hook *hook));
1203     void (*deregister_hooks)(int version,
1204        int (*deregister_hook)(struct sudo_hook *hook));
1205 };
1206 .Ed
1207 .Pp
1208 When an I/O plugin is loaded,
1209 .Nm sudo
1210 runs the command in a pseudo-tty.
1211 This makes it possible to log the input and output from the user's
1212 session.
1213 If any of the standard input, standard output or standard error do not
1214 correspond to a tty,
1215 .Nm sudo
1216 will open a pipe to capture
1217 the I/O for logging before passing it on.
1218 .Pp
1219 The log_ttyin function receives the raw user input from the terminal
1220 device (note that this will include input even when echo is disabled,
1221 such as when a password is read).
1222 The log_ttyout function receives output from the pseudo-tty that is
1223 suitable for replaying the user's session at a later time.
1224 The
1225 .Fn log_stdin ,
1226 .Fn log_stdout
1227 and
1228 .Fn log_stderr
1229 functions are only called if the standard input, standard output
1230 or standard error respectively correspond to something other than
1231 a tty.
1232 .Pp
1233 Any of the logging functions may be set to the
1234 .Dv NULL
1235 pointer if no logging is to be performed.
1236 If the open function returns 0, no I/O will be sent to the plugin.
1237 .Pp
1238 The io_plugin struct has the following fields:
1239 .Bl -tag -width 4n
1240 .It type
1241 The
1242 .Li type
1243 field should always be set to
1244 .Dv SUDO_IO_PLUGIN .
1245 .It version
1246 The
1247 .Li version
1248 field should be set to
1249 .Dv SUDO_API_VERSION .
1250 .Pp
1251 This allows
1252 .Nm sudo
1253 to determine the API version the plugin was
1254 built against.
1255 .It open
1256 .Bd -literal -compact
1257 int (*open)(unsigned int version, sudo_conv_t conversation,
1258             sudo_printf_t plugin_printf, char * const settings[],
1259             char * const user_info[], int argc, char * const argv[],
1260             char * const user_env[], char * const plugin_options[]);
1261 .Ed
1262 .Pp
1263 The
1264 .Fn open
1265 function is run before the
1266 .Fn log_input ,
1267 .Fn log_output
1268 or
1269 .Fn show_version
1270 functions are called.
1271 It is only called if the version is being requested or the
1272 .Fn check_policy
1273 function has
1274 returned successfully.
1275 It returns 1 on success, 0 on failure, \-1 if a general error occurred,
1276 or \-2 if there was a usage error.
1277 In the latter case,
1278 .Nm sudo
1279 will print a usage message before it exits.
1280 If an error occurs, the plugin may optionally call the
1281 .Fn conversation
1282 or
1283 .Fn plugin_printf
1284 function with
1285 .Dv SUDO_CONF_ERROR_MSG
1286 to present
1287 additional error information to the user.
1288 .Pp
1289 The function arguments are as follows:
1290 .Bl -tag -width 4n
1291 .It version
1292 The version passed in by
1293 .Nm sudo
1294 allows the plugin to determine the
1295 major and minor version number of the plugin API supported by
1296 .Nm sudo .
1297 .It conversation
1298 A pointer to the
1299 .Fn conversation
1300 function that may be used by the
1301 .Fn show_version
1302 function to display version information (see
1303 .Fn show_version
1304 below).
1305 The
1306 .Fn conversation
1307 function may also be used to display additional error message to the user.
1308 The
1309 .Fn conversation
1310 function returns 0 on success and \-1 on failure.
1311 .It plugin_printf
1312 A pointer to a
1313 .Fn printf Ns No -style
1314 function that may be used by the
1315 .Fn show_version
1316 function to display version information (see
1317 show_version below).
1318 The
1319 .Fn plugin_printf
1320 function may also be used to display additional error message to the user.
1321 The
1322 .Fn plugin_printf
1323 function returns number of characters printed on success and \-1 on failure.
1324 .It settings
1325 A vector of user-supplied
1326 .Nm sudo
1327 settings in the form of
1328 .Dq name=value
1329 strings.
1330 The vector is terminated by a
1331 .Dv NULL
1332 pointer.
1333 These settings correspond to flags the user specified when running
1334 .Nm sudo .
1335 As such, they will only be present when the corresponding flag has
1336 been specified on the command line.
1337 .Pp
1338 When parsing
1339 .Em settings ,
1340 the plugin should split on the
1341 .Sy first
1342 equal sign
1343 .Pq Ql =
1344 since the
1345 .Em name
1346 field will never include one
1347 itself but the
1348 .Em value
1349 might.
1350 .Pp
1351 See the
1352 .Sx Policy plugin API
1353 section for a list of all possible settings.
1354 .It user_info
1355 A vector of information about the user running the command in the form of
1356 .Dq name=value
1357 strings.
1358 The vector is terminated by a
1359 .Dv NULL
1360 pointer.
1361 .Pp
1362 When parsing
1363 .Em user_info ,
1364 the plugin should split on the
1365 .Sy first
1366 equal sign
1367 .Pq Ql =
1368 since the
1369 .Em name
1370 field will never include one
1371 itself but the
1372 .Em value
1373 might.
1374 .Pp
1375 See the
1376 .Sx Policy plugin API
1377 section for a list of all possible strings.
1378 .It argc
1379 The number of elements in
1380 .Em argv ,
1381 not counting the final
1382 .Dv NULL
1383 pointer.
1384 .It argv
1385 If
1386 .No non- Ns Dv NULL ,
1387 an argument vector describing a command the user
1388 wishes to run in the same form as what would be passed to the
1389 .Xr execve 2
1390 system call.
1391 .It user_env
1392 The user's environment in the form of a
1393 .Dv NULL Ns No -terminated
1394 vector of
1395 .Dq name=value
1396 strings.
1397 .Pp
1398 When parsing
1399 .Em user_env ,
1400 the plugin should split on the
1401 .Sy first
1402 equal sign
1403 .Pq Ql =
1404 since the
1405 .Em name
1406 field will never include one
1407 itself but the
1408 .Em value
1409 might.
1410 .It plugin_options
1411 Any (non-comment) strings immediately after the plugin path are
1412 treated as arguments to the plugin.
1413 These arguments are split on a white space boundary and are passed to
1414 the plugin in the form of a
1415 .Dv NULL Ns No -terminated
1416 array of strings.
1417 If no arguments were specified,
1418 .Em plugin_options
1419 will be the
1420 .Dv NULL
1421 pointer.
1422 .Pp
1423 NOTE: the
1424 .Em plugin_options
1425 parameter is only available starting with
1426 API version 1.2.
1427 A plugin
1428 .Sy must
1429 check the API version specified
1430 by the
1431 .Nm sudo
1432 front end before using
1433 .Em plugin_options .
1434 Failure to do so may result in a crash.
1435 .El
1436 .It close
1437 .Bd -literal -compact
1438 void (*close)(int exit_status, int error);
1439 .Ed
1440 .Pp
1441 The
1442 .Fn close
1443 function is called when the command being run by
1444 .Nm sudo
1445 finishes.
1446 .Pp
1447 The function arguments are as follows:
1448 .Bl -tag -width 4n
1449 .It exit_status
1450 The command's exit status, as returned by the
1451 .Xr wait 2
1452 system call.
1453 The value of
1454 .Li exit_status
1455 is undefined if
1456 .Li error
1457 is non-zero.
1458 .It error
1459 If the command could not be executed, this is set to the value of
1460 .Li errno
1461 set by the
1462 .Xr execve 2
1463 system call.
1464 If the command was successfully executed, the value of
1465 .Li error
1466 is 0.
1467 .El
1468 .It show_version
1469 .Bd -literal -compact
1470 int (*show_version)(int verbose);
1471 .Ed
1472 .Pp
1473 The
1474 .Fn show_version
1475 function is called by
1476 .Nm sudo
1477 when the user specifies
1478 the
1479 .Fl V
1480 option.
1481 The plugin may display its version information to the user via the
1482 .Fn conversation
1483 or
1484 .Fn plugin_printf
1485 function using
1486 .Dv SUDO_CONV_INFO_MSG .
1487 If the user requests detailed version information, the verbose flag will be set.
1488 .It log_ttyin
1489 .Bd -literal -compact
1490 int (*log_ttyin)(const char *buf, unsigned int len);
1491 .Ed
1492 .Pp
1493 The
1494 .Fn log_ttyin
1495 function is called whenever data can be read from
1496 the user but before it is passed to the running command.
1497 This allows the plugin to reject data if it chooses to (for instance
1498 if the input contains banned content).
1499 Returns 1 if the data should be passed to the command, 0 if the data
1500 is rejected (which will terminate the command) or \-1 if an error occurred.
1501 .Pp
1502 The function arguments are as follows:
1503 .Bl -tag -width 4n
1504 .It buf
1505 The buffer containing user input.
1506 .It len
1507 The length of
1508 .Em buf
1509 in bytes.
1510 .El
1511 .It log_ttyout
1512 .Bd -literal -compact
1513 int (*log_ttyout)(const char *buf, unsigned int len);
1514 .Ed
1515 .Pp
1516 The
1517 .Fn log_ttyout
1518 function is called whenever data can be read from
1519 the command but before it is written to the user's terminal.
1520 This allows the plugin to reject data if it chooses to (for instance
1521 if the output contains banned content).
1522 Returns 1 if the data should be passed to the user, 0 if the data is rejected
1523 (which will terminate the command) or \-1 if an error occurred.
1524 .Pp
1525 The function arguments are as follows:
1526 .Bl -tag -width 4n
1527 .It buf
1528 The buffer containing command output.
1529 .It len
1530 The length of
1531 .Em buf
1532 in bytes.
1533 .El
1534 .It log_stdin
1535 .Bd -literal -compact
1536 int (*log_stdin)(const char *buf, unsigned int len);
1537 .Ed
1538 .Pp
1539 The
1540 .Fn log_stdin
1541 function is only used if the standard input does
1542 not correspond to a tty device.
1543 It is called whenever data can be read from the standard input but
1544 before it is passed to the running command.
1545 This allows the plugin to reject data if it chooses to
1546 (for instance if the input contains banned content).
1547 Returns 1 if the data should be passed to the command, 0 if the data is
1548 rejected (which will terminate the command) or \-1 if an error occurred.
1549 .Pp
1550 The function arguments are as follows:
1551 .Bl -tag -width 4n
1552 .It buf
1553 The buffer containing user input.
1554 .It len
1555 The length of
1556 .Em buf
1557 in bytes.
1558 .El
1559 .It log_stdout
1560 .Bd -literal -compact
1561 int (*log_stdout)(const char *buf, unsigned int len);
1562 .Ed
1563 .Pp
1564 The
1565 .Fn log_stdout
1566 function is only used if the standard output does not correspond
1567 to a tty device.
1568 It is called whenever data can be read from the command but before
1569 it is written to the standard output.
1570 This allows the plugin to reject data if it chooses to
1571 (for instance if the output contains banned content).
1572 Returns 1 if the data should be passed to the user, 0 if the data is
1573 rejected (which will terminate the command) or \-1 if an error occurred.
1574 .Pp
1575 The function arguments are as follows:
1576 .Bl -tag -width 4n
1577 .It buf
1578 The buffer containing command output.
1579 .It len
1580 The length of
1581 .Em buf
1582 in bytes.
1583 .El
1584 .It log_stderr
1585 .Bd -literal -compact
1586 int (*log_stderr)(const char *buf, unsigned int len);
1587 .Ed
1588 .Pp
1589 The
1590 .Fn log_stderr
1591 function is only used if the standard error does
1592 not correspond to a tty device.
1593 It is called whenever data can be read from the command but before it
1594 is written to the standard error.
1595 This allows the plugin to reject data if it chooses to
1596 (for instance if the output contains banned content).
1597 Returns 1 if the data should be passed to the user, 0 if the data is
1598 rejected (which will terminate the command) or \-1 if an error occurred.
1599 .Pp
1600 The function arguments are as follows:
1601 .Bl -tag -width 4n
1602 .It buf
1603 The buffer containing command output.
1604 .It len
1605 The length of
1606 .Em buf
1607 in bytes.
1608 .El
1609 .It register_hooks
1610 See the
1611 .Sx Policy plugin API
1612 section for a description of
1613 .Li register_hooks .
1614 .It deregister_hooks
1615 See the
1616 .Sx Policy plugin API
1617 section for a description of
1618 .Li deregister_hooks.
1619 .El
1620 .Pp
1621 .Em I/O Plugin Version Macros
1622 .Pp
1623 Same as for the
1624 .Sx Policy plugin API .
1625 .Ss Signal handlers
1626 The
1627 .Nm sudo
1628 front end installs default signal handlers to trap common signals
1629 while the plugin functions are run.
1630 The following signals are trapped by default before the command is
1631 executed:
1632 .Pp
1633 .Bl -bullet -compact
1634 .It
1635 .Dv SIGALRM
1636 .It
1637 .Dv SIGHUP
1638 .It
1639 .Dv SIGINT
1640 .It
1641 .Dv SIGQUIT
1642 .It
1643 .Dv SIGTERM
1644 .It
1645 .Dv SIGTSTP
1646 .It
1647 .Dv SIGUSR1
1648 .It
1649 .Dv SIGUSR2
1650 .El
1651 .Pp
1652 If a fatal signal is received before the command is executed,
1653 .Nm sudo
1654 will call the plugin's
1655 .Fn close
1656 function with an exit status of 128 plus the value of the signal
1657 that was received.
1658 This allows for consistent logging of commands killed by a signal
1659 for plugins that log such information in their
1660 .Fn close
1661 function.
1662 .Pp
1663 A plugin may temporarily install its own signal handlers but must
1664 restore the original handler before the plugin function returns.
1665 .Ss Hook function API
1666 Beginning with plugin API version 1.2, it is possible to install
1667 hooks for certain functions called by the
1668 .Nm sudo
1669 front end.
1670 .Pp
1671 Currently, the only supported hooks relate to the handling of
1672 environment variables.
1673 Hooks can be used to intercept attempts to get, set, or remove
1674 environment variables so that these changes can be reflected in
1675 the version of the environment that is used to execute a command.
1676 A future version of the API will support hooking internal
1677 .Nm sudo
1678 front end functions as well.
1679 .Pp
1680 .Em Hook structure
1681 .Pp
1682 Hooks in
1683 .Nm sudo
1684 are described by the following structure:
1685 .Bd -literal
1686 typedef int (*sudo_hook_fn_t)();
1687
1688 struct sudo_hook {
1689     int hook_version;
1690     int hook_type;
1691     sudo_hook_fn_t hook_fn;
1692     void *closure;
1693 };
1694 .Ed
1695 .Pp
1696 The
1697 .Li sudo_hook
1698 structure has the following fields:
1699 .Bl -tag -width 4n
1700 .It hook_version
1701 The
1702 .Li hook_version
1703 field should be set to
1704 .Dv SUDO_HOOK_VERSION .
1705 .It hook_type
1706 The
1707 .Li hook_type
1708 field may be one of the following supported hook types:
1709 .Bl -tag -width 4n
1710 .It Dv SUDO_HOOK_SETENV
1711 The C library
1712 .Xr setenv 3
1713 function.
1714 Any registered hooks will run before the C library implementation.
1715 The
1716 .Li hook_fn
1717 field should
1718 be a function that matches the following typedef:
1719 .Bd -literal
1720 typedef int (*sudo_hook_fn_setenv_t)(const char *name,
1721    const char *value, int overwrite, void *closure);
1722 .Ed
1723 .Pp
1724 If the registered hook does not match the typedef the results are
1725 unspecified.
1726 .It Dv SUDO_HOOK_UNSETENV
1727 The C library
1728 .Xr unsetenv 3
1729 function.
1730 Any registered hooks will run before the C library implementation.
1731 The
1732 .Li hook_fn
1733 field should
1734 be a function that matches the following typedef:
1735 .Bd -literal
1736 typedef int (*sudo_hook_fn_unsetenv_t)(const char *name,
1737    void *closure);
1738 .Ed
1739 .It Dv SUDO_HOOK_GETENV
1740 The C library
1741 .Xr getenv 3
1742 function.
1743 Any registered hooks will run before the C library implementation.
1744 The
1745 .Li hook_fn
1746 field should
1747 be a function that matches the following typedef:
1748 .Bd -literal
1749 typedef int (*sudo_hook_fn_getenv_t)(const char *name,
1750    char **value, void *closure);
1751 .Ed
1752 .Pp
1753 If the registered hook does not match the typedef the results are
1754 unspecified.
1755 .It Dv SUDO_HOOK_PUTENV
1756 The C library
1757 .Xr putenv 3
1758 function.
1759 Any registered hooks will run before the C library implementation.
1760 The
1761 .Li hook_fn
1762 field should
1763 be a function that matches the following typedef:
1764 .Bd -literal
1765 typedef int (*sudo_hook_fn_putenv_t)(char *string,
1766    void *closure);
1767 .Ed
1768 .Pp
1769 If the registered hook does not match the typedef the results are
1770 unspecified.
1771 .El
1772 .It hook_fn
1773 sudo_hook_fn_t hook_fn;
1774 .Pp
1775 The
1776 .Li hook_fn
1777 field should be set to the plugin's hook implementation.
1778 The actual function arguments will vary depending on the
1779 .Li hook_type
1780 (see
1781 .Li hook_type
1782 above).
1783 In all cases, the
1784 .Li closure
1785 field of
1786 .Li struct sudo_hook
1787 is passed as the last function parameter.
1788 This can be used to pass arbitrary data to the plugin's hook implementation.
1789 .Pp
1790 The function return value may be one of the following:
1791 .Bl -tag -width 4n
1792 .It Dv SUDO_HOOK_RET_ERROR
1793 The hook function encountered an error.
1794 .It Dv SUDO_HOOK_RET_NEXT
1795 The hook completed without error, go on to the next hook (including
1796 the native implementation if applicable).
1797 For example, a
1798 .Xr getenv 3
1799 hook might return
1800 .Dv SUDO_HOOK_RET_NEXT
1801 if the specified variable was not found in the private copy of the environment.
1802 .It Dv SUDO_HOOK_RET_STOP
1803 The hook completed without error, stop processing hooks for this invocation.
1804 This can be used to replace the native implementation.
1805 For example, a
1806 .Li setenv
1807 hook that operates on a private copy of
1808 the environment but leaves
1809 .Li environ
1810 unchanged.
1811 .El
1812 .El
1813 .Pp
1814 Note that it is very easy to create an infinite loop when hooking
1815 C library functions.
1816 For example, a
1817 .Xr getenv 3
1818 hook that calls the
1819 .Xr snprintf 3
1820 function may create a loop if the
1821 .Xr snprintf 3
1822 implementation calls
1823 .Xr getenv 3
1824 to check the locale.
1825 To prevent this, you may wish to use a static variable in the hook
1826 function to guard against nested calls.
1827 For example:
1828 .Bd -literal
1829 static int in_progress = 0; /* avoid recursion */
1830 if (in_progress)
1831     return SUDO_HOOK_RET_NEXT;
1832 in_progress = 1;
1833 \&...
1834 in_progress = 0;
1835 return SUDO_HOOK_RET_STOP;
1836 .Ed
1837 .Pp
1838 .Em Hook API Version Macros
1839 .Bd -literal
1840 /* Hook API version major/minor */
1841 #define SUDO_HOOK_VERSION_MAJOR 1
1842 #define SUDO_HOOK_VERSION_MINOR 0
1843 #define SUDO_HOOK_MKVERSION(x, y) ((x << 16) | y)
1844 #define SUDO_HOOK_VERSION SUDO_HOOK_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\e
1845                                               SUDO_HOOK_VERSION_MINOR)
1846
1847 /* Getters and setters for hook API version */
1848 #define SUDO_HOOK_VERSION_GET_MAJOR(v) ((v) >> 16)
1849 #define SUDO_HOOK_VERSION_GET_MINOR(v) ((v) & 0xffff)
1850 #define SUDO_HOOK_VERSION_SET_MAJOR(vp, n) do { \e
1851     *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
1852 } while(0)
1853 #define SUDO_HOOK_VERSION_SET_MINOR(vp, n) do { \e
1854     *(vp) = (*(vp) & 0xffff0000) | (n); \e
1855 } while(0)
1856 .Ed
1857 .Ss Conversation API
1858 If the plugin needs to interact with the user, it may do so via the
1859 .Fn conversation
1860 function.
1861 A plugin should not attempt to read directly from the standard input
1862 or the user's tty (neither of which are guaranteed to exist).
1863 The caller must include a trailing newline in
1864 .Li msg
1865 if one is to be printed.
1866 .Pp
1867 A
1868 .Fn printf Ns No -style
1869 function is also available that can be used to display informational
1870 or error messages to the user, which is usually more convenient for
1871 simple messages where no use input is required.
1872 .Bd -literal
1873 struct sudo_conv_message {
1874 #define SUDO_CONV_PROMPT_ECHO_OFF  0x0001 /* do not echo user input */
1875 #define SUDO_CONV_PROMPT_ECHO_ON   0x0002 /* echo user input */
1876 #define SUDO_CONV_ERROR_MSG        0x0003 /* error message */
1877 #define SUDO_CONV_INFO_MSG         0x0004 /* informational message */
1878 #define SUDO_CONV_PROMPT_MASK      0x0005 /* mask user input */
1879 #define SUDO_CONV_DEBUG_MSG        0x0006 /* debugging message */
1880 #define SUDO_CONV_PROMPT_ECHO_OK   0x1000 /* flag: allow echo if no tty */
1881     int msg_type;
1882     int timeout;
1883     const char *msg;
1884 };
1885
1886 struct sudo_conv_reply {
1887     char *reply;
1888 };
1889
1890 typedef int (*sudo_conv_t)(int num_msgs,
1891              const struct sudo_conv_message msgs[],
1892              struct sudo_conv_reply replies[]);
1893
1894 typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
1895 .Ed
1896 .Pp
1897 Pointers to the
1898 .Fn conversation
1899 and
1900 .Fn printf Ns No -style
1901 functions are passed
1902 in to the plugin's
1903 .Fn open
1904 function when the plugin is initialized.
1905 .Pp
1906 To use the
1907 .Fn conversation
1908 function, the plugin must pass an array of
1909 .Li sudo_conv_message
1910 and
1911 .Li sudo_conv_reply
1912 structures.
1913 There must be a
1914 .Li struct sudo_conv_message
1915 and
1916 .Li struct sudo_conv_reply
1917 for
1918 each message in the conversation.
1919 The plugin is responsible for freeing the reply buffer filled in to the
1920 .Li struct sudo_conv_reply ,
1921 if any.
1922 .Pp
1923 The
1924 .Fn printf Ns No -style
1925 function uses the same underlying mechanism as the
1926 .Fn conversation
1927 function but only supports
1928 .Dv SUDO_CONV_INFO_MSG ,
1929 .Dv SUDO_CONV_ERROR_MSG
1930 and
1931 .Dv SUDO_CONV_DEBUG_MSG
1932 for the
1933 .Em msg_type
1934 parameter.
1935 It can be more convenient than using the
1936 .Fn conversation
1937 function if no user reply is needed and supports standard
1938 .Fn printf
1939 escape sequences.
1940 .Pp
1941 Unlike,
1942 .Dv SUDO_CONV_INFO_MSG
1943 and
1944 Dv SUDO_CONV_ERROR_MSG ,
1945 messages
1946 sent with the
1947 .Dv SUDO_CONV_DEBUG_MSG
1948 .Em msg_type
1949 are not directly
1950 user-visible.
1951 Instead, they are logged to the file specified in the
1952 .Li Debug
1953 statement (if any) in the
1954 .Xr sudo.conf @mansectform@ .
1955 file.
1956 This allows a plugin to log debugging information and is intended
1957 to be used in conjunction with the
1958 .Em debug_flags
1959 setting.
1960 .Pp
1961 See the sample plugin for an example of the
1962 .Fn conversation
1963 function usage.
1964 .Ss Sudoers group plugin API
1965 The
1966 .Nm sudoers
1967 plugin supports its own plugin interface to allow non-Unix
1968 group lookups.
1969 This can be used to query a group source other than the standard Unix
1970 group database.
1971 Two sample group plugins are bundled with
1972 .Nm sudo ,
1973 .Em group_file
1974 and
1975 .Em system_group ,
1976 are detailed in
1977 .Xr sudoers @mansectform@ .
1978 Third party group plugins include a QAS AD plugin available from Quest Software.
1979 .Pp
1980 A group plugin must declare and populate a
1981 .Li sudoers_group_plugin
1982 struct in the global scope.
1983 This structure contains pointers to the functions that implement plugin
1984 initialization, cleanup and group lookup.
1985 .Bd -literal
1986 struct sudoers_group_plugin {
1987    unsigned int version;
1988    int (*init)(int version, sudo_printf_t sudo_printf,
1989                char *const argv[]);
1990    void (*cleanup)(void);
1991    int (*query)(const char *user, const char *group,
1992                 const struct passwd *pwd);
1993 };
1994 .Ed
1995 .Pp
1996 The
1997 .Li sudoers_group_plugin
1998 struct has the following fields:
1999 .Bl -tag -width 4n
2000 .It version
2001 The
2002 .Li version
2003 field should be set to GROUP_API_VERSION.
2004 .Pp
2005 This allows
2006 .Nm sudoers
2007 to determine the API version the group plugin
2008 was built against.
2009 .It init
2010 .Bd -literal -compact
2011 int (*init)(int version, sudo_printf_t plugin_printf,
2012             char *const argv[]);
2013 .Ed
2014 .Pp
2015 The
2016 .Fn init
2017 function is called after
2018 .Em sudoers
2019 has been parsed but
2020 before any policy checks.
2021 It returns 1 on success, 0 on failure (or if the plugin is not configured),
2022 and \-1 if a error occurred.
2023 If an error occurs, the plugin may call the
2024 .Fn plugin_printf
2025 function with
2026 .Dv SUDO_CONF_ERROR_MSG
2027 to present additional error information
2028 to the user.
2029 .Pp
2030 The function arguments are as follows:
2031 .Bl -tag -width 4n
2032 .It version
2033 The version passed in by
2034 .Nm sudoers
2035 allows the plugin to determine the
2036 major and minor version number of the group plugin API supported by
2037 .Nm sudoers .
2038 .It plugin_printf
2039 A pointer to a
2040 .Fn printf Ns No -style
2041 function that may be used to display informational or error message to the user.
2042 Returns the number of characters printed on success and \-1 on failure.
2043 .It argv
2044 A
2045 .Dv NULL Ns No -terminated
2046 array of arguments generated from the
2047 .Em group_plugin
2048 option in
2049 .Em sudoers .
2050 If no arguments were given,
2051 .Em argv
2052 will be
2053 .Dv NULL .
2054 .El
2055 .It cleanup
2056 .Bd -literal -compact
2057 void (*cleanup)();
2058 .Ed
2059 .Pp
2060 The
2061 .Fn cleanup
2062 function is called when
2063 .Nm sudoers
2064 has finished its
2065 group checks.
2066 The plugin should free any memory it has allocated and close open file handles.
2067 .It query
2068 .Bd -literal -compact
2069 int (*query)(const char *user, const char *group,
2070              const struct passwd *pwd);
2071 .Ed
2072 .Pp
2073 The
2074 .Fn query
2075 function is used to ask the group plugin whether
2076 .Em user
2077 is a member of
2078 .Em group .
2079 .Pp
2080 The function arguments are as follows:
2081 .Bl -tag -width 4n
2082 .It user
2083 The name of the user being looked up in the external group database.
2084 .It group
2085 The name of the group being queried.
2086 .It pwd
2087 The password database entry for
2088 .Em user ,
2089 if any.
2090 If
2091 .Em user
2092 is not
2093 present in the password database,
2094 .Em pwd
2095 will be
2096 .Dv NULL .
2097 .El
2098 .El
2099 .Pp
2100 .Em Group API Version Macros
2101 .Bd -literal
2102 /* Sudoers group plugin version major/minor */
2103 #define GROUP_API_VERSION_MAJOR 1
2104 #define GROUP_API_VERSION_MINOR 0
2105 #define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \e
2106                            GROUP_API_VERSION_MINOR)
2107
2108 /* Getters and setters for group version */
2109 #define GROUP_API_VERSION_GET_MAJOR(v) ((v) >> 16)
2110 #define GROUP_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
2111 #define GROUP_API_VERSION_SET_MAJOR(vp, n) do { \e
2112     *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
2113 } while(0)
2114 #define GROUP_API_VERSION_SET_MINOR(vp, n) do { \e
2115     *(vp) = (*(vp) & 0xffff0000) | (n); \e
2116 } while(0)
2117 .Ed
2118 .Sh PLUGIN API CHANGELOG
2119 The following revisions have been made to the Sudo Plugin API.
2120 .Bl -tag -width 4n
2121 .It Version 1.0
2122 Initial API version.
2123 .It Version 1.1 (sudo 1.8.0)
2124 The I/O logging plugin's
2125 .Fn open
2126 function was modified to take the
2127 .Li command_info
2128 list as an argument.
2129 .It Version 1.2 (sudo 1.8.5)
2130 The Policy and I/O logging plugins'
2131 .Fn open
2132 functions are now passed
2133 a list of plugin parameters if any are specified in
2134 .Xr sudo.conf @mansectform@ .
2135 .Pp
2136 A simple hooks API has been introduced to allow plugins to hook in to the
2137 system's environment handling functions.
2138 .Pp
2139 The
2140 .Li init_session
2141 Policy plugin function is now passed a pointer
2142 to the user environment which can be updated as needed.
2143 This can be used to merge in environment variables stored in the PAM
2144 handle before a command is run.
2145 .It Version 1.3 (sudo 1.8.7)
2146 Support for the
2147 .Em exec_background
2148 entry has been added to the
2149 .Li command_info
2150 list.
2151 .Pp
2152 The
2153 .Em max_groups
2154 and
2155 .Em plugin_dir
2156 entries were added to the
2157 .Li settings
2158 list.
2159 .Pp
2160 The
2161 .Fn version
2162 and
2163 .Fn close
2164 functions are now optional.
2165 Previously, a missing
2166 .Fn version
2167 or
2168 .Fn close
2169 function would result in a crash.
2170 If no policy plugin
2171 .Fn close
2172 function is defined, a default
2173 .Fn close
2174 function will be provided by the
2175 .Nm sudo
2176 front end that displays a warning if the command could not be
2177 executed.
2178 .Pp
2179 The
2180 .Nm sudo
2181 front end now installs default signal handlers to trap common signals
2182 while the plugin functions are run.
2183 .El
2184 .Sh SEE ALSO
2185 .Xr sudo.conf @mansectform@ ,
2186 .Xr sudoers @mansectform@ ,
2187 .Xr sudo @mansectsu@
2188 .Sh BUGS
2189 If you feel you have found a bug in
2190 .Nm sudo ,
2191 please submit a bug report at http://www.sudo.ws/sudo/bugs/
2192 .Sh SUPPORT
2193 Limited free support is available via the sudo-users mailing list,
2194 see http://www.sudo.ws/mailman/listinfo/sudo-users to subscribe or
2195 search the archives.
2196 .Sh DISCLAIMER
2197 .Nm sudo
2198 is provided
2199 .Dq AS IS
2200 and any express or implied warranties, including, but not limited
2201 to, the implied warranties of merchantability and fitness for a
2202 particular purpose are disclaimed.
2203 See the LICENSE file distributed with
2204 .Nm sudo
2205 or http://www.sudo.ws/sudo/license.html for complete details.