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