Imported Upstream version 1.8.5
[debian/sudo] / doc / sudo_plugin.man.in
1 .\" Copyright (c) 2009-2012 Todd C. Miller <Todd.Miller@courtesan.com>
2 .\" 
3 .\" Permission to use, copy, modify, and distribute this software for any
4 .\" purpose with or without fee is hereby granted, provided that the above
5 .\" copyright notice and this permission notice appear in all copies.
6 .\" 
7 .\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 .\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 .\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 .\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 .\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15 .\" 
16 .\" Automatically generated by Pod::Man 2.23 (Pod::Simple 3.14)
17 .\"
18 .\" Standard preamble:
19 .\" ========================================================================
20 .de Sp \" Vertical space (when we can't use .PP)
21 .if t .sp .5v
22 .if n .sp
23 ..
24 .de Vb \" Begin verbatim text
25 .ft CW
26 .nf
27 .ne \\$1
28 ..
29 .de Ve \" End verbatim text
30 .ft R
31 .fi
32 ..
33 .\" Set up some character translations and predefined strings.  \*(-- will
34 .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
35 .\" double quote, and \*(R" will give a right double quote.  \*(C+ will
36 .\" give a nicer C++.  Capital omega is used to do unbreakable dashes and
37 .\" therefore won't be available.  \*(C` and \*(C' expand to `' in nroff,
38 .\" nothing in troff, for use with C<>.
39 .tr \(*W-
40 .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
41 .ie n \{\
42 .    ds -- \(*W-
43 .    ds PI pi
44 .    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
45 .    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
46 .    ds L" ""
47 .    ds R" ""
48 .    ds C` 
49 .    ds C' 
50 'br\}
51 .el\{\
52 .    ds -- \|\(em\|
53 .    ds PI \(*p
54 .    ds L" ``
55 .    ds R" ''
56 'br\}
57 .\"
58 .\" Escape single quotes in literal strings from groff's Unicode transform.
59 .ie \n(.g .ds Aq \(aq
60 .el       .ds Aq '
61 .\"
62 .\" If the F register is turned on, we'll generate index entries on stderr for
63 .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
64 .\" entries marked with X<> in POD.  Of course, you'll have to process the
65 .\" output yourself in some meaningful fashion.
66 .ie \nF \{\
67 .    de IX
68 .    tm Index:\\$1\t\\n%\t"\\$2"
69 ..
70 .    nr % 0
71 .    rr F
72 .\}
73 .el \{\
74 .    de IX
75 ..
76 .\}
77 .\"
78 .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
79 .\" Fear.  Run.  Save yourself.  No user-serviceable parts.
80 .    \" fudge factors for nroff and troff
81 .if n \{\
82 .    ds #H 0
83 .    ds #V .8m
84 .    ds #F .3m
85 .    ds #[ \f1
86 .    ds #] \fP
87 .\}
88 .if t \{\
89 .    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
90 .    ds #V .6m
91 .    ds #F 0
92 .    ds #[ \&
93 .    ds #] \&
94 .\}
95 .    \" simple accents for nroff and troff
96 .if n \{\
97 .    ds ' \&
98 .    ds ` \&
99 .    ds ^ \&
100 .    ds , \&
101 .    ds ~ ~
102 .    ds /
103 .\}
104 .if t \{\
105 .    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
106 .    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
107 .    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
108 .    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
109 .    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
110 .    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
111 .\}
112 .    \" troff and (daisy-wheel) nroff accents
113 .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
114 .ds 8 \h'\*(#H'\(*b\h'-\*(#H'
115 .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
116 .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
117 .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
118 .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
119 .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
120 .ds ae a\h'-(\w'a'u*4/10)'e
121 .ds Ae A\h'-(\w'A'u*4/10)'E
122 .    \" corrections for vroff
123 .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
124 .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
125 .    \" for low resolution devices (crt and lpr)
126 .if \n(.H>23 .if \n(.V>19 \
127 \{\
128 .    ds : e
129 .    ds 8 ss
130 .    ds o a
131 .    ds d- d\h'-1'\(ga
132 .    ds D- D\h'-1'\(hy
133 .    ds th \o'bp'
134 .    ds Th \o'LP'
135 .    ds ae ae
136 .    ds Ae AE
137 .\}
138 .rm #[ #] #H #V #F C
139 .\" ========================================================================
140 .\"
141 .IX Title "SUDO_PLUGIN @mansectsu@"
142 .TH SUDO_PLUGIN @mansectsu@ "April 23, 2012" "1.8.5" "MAINTENANCE COMMANDS"
143 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
144 .\" way too many mistakes in technical documents.
145 .if n .ad l
146 .nh
147 .SH "NAME"
148 sudo_plugin \- Sudo Plugin API
149 .SH "DESCRIPTION"
150 .IX Header "DESCRIPTION"
151 Starting with version 1.8, \fBsudo\fR supports a plugin \s-1API\s0
152 for policy and session logging.  By default, the \fIsudoers\fR policy
153 plugin and an associated I/O logging plugin are used.  Via the plugin
154 \&\s-1API\s0, \fBsudo\fR can be configured to use alternate policy and/or I/O
155 logging plugins provided by third parties.  The plugins to be used
156 are specified via the \fI@sysconfdir@/sudo.conf\fR file.
157 .PP
158 The \s-1API\s0 is versioned with a major and minor number.  The minor
159 version number is incremented when additions are made.  The major
160 number is incremented when incompatible changes are made.  A plugin
161 should be check the version passed to it and make sure that the
162 major version matches.
163 .PP
164 The plugin \s-1API\s0 is defined by the \f(CW\*(C`sudo_plugin.h\*(C'\fR header file.
165 .SS "The sudo.conf File"
166 .IX Subsection "The sudo.conf File"
167 The \fI@sysconfdir@/sudo.conf\fR file contains plugin configuration directives.
168 Currently, the only supported keyword is the \f(CW\*(C`Plugin\*(C'\fR directive,
169 which causes a plugin plugin to be loaded.
170 .PP
171 A \f(CW\*(C`Plugin\*(C'\fR line consists of the \f(CW\*(C`Plugin\*(C'\fR keyword, followed by the
172 \&\fIsymbol_name\fR and the \fIpath\fR to the shared object containing the
173 plugin.  The \fIsymbol_name\fR is the name of the \f(CW\*(C`struct policy_plugin\*(C'\fR
174 or \f(CW\*(C`struct io_plugin\*(C'\fR in the plugin shared object.  The \fIpath\fR
175 may be fully qualified or relative.  If not fully qualified it is
176 relative to the \fI@prefix@/libexec\fR directory.  Any additional
177 parameters after the \fIpath\fR are passed as options to the plugin's
178 \&\fIopen\fR function.  Lines that don't begin with \f(CW\*(C`Plugin\*(C'\fR, \f(CW\*(C`Path\*(C'\fR,
179 \&\f(CW\*(C`Debug\*(C'\fR or \f(CW\*(C`Set\*(C'\fR are silently ignored.
180 .PP
181 The same shared object may contain multiple plugins, each with a
182 different symbol name.  The shared object file must be owned by uid
183 0 and only writable by its owner.  Because of ambiguities that arise
184 from composite policies, only a single policy plugin may be specified.
185 This limitation does not apply to I/O plugins.
186 .PP
187 .Vb 10
188 \& #
189 \& # Default @sysconfdir@/sudo.conf file
190 \& #
191 \& # Format:
192 \& #   Plugin plugin_name plugin_path plugin_options ...
193 \& #   Path askpass /path/to/askpass
194 \& #   Path noexec /path/to/sudo_noexec.so
195 \& #   Debug sudo /var/log/sudo_debug all@warn
196 \& #   Set disable_coredump true
197 \& #
198 \& # The plugin_path is relative to @prefix@/libexec unless
199 \& #   fully qualified.
200 \& # The plugin_name corresponds to a global symbol in the plugin
201 \& #   that contains the plugin interface structure.
202 \& # The plugin_options are optional.
203 \& #
204 \& Plugin sudoers_policy sudoers.so
205 \& Plugin sudoers_io sudoers.so
206 .Ve
207 .SS "Policy Plugin \s-1API\s0"
208 .IX Subsection "Policy Plugin API"
209 A policy plugin must declare and populate a \f(CW\*(C`policy_plugin\*(C'\fR struct
210 in the global scope.  This structure contains pointers to the functions
211 that implement the \fBsudo\fR policy checks.  The name of the symbol should
212 be specified in \fI@sysconfdir@/sudo.conf\fR along with a path to the plugin
213 so that \fBsudo\fR can load it.
214 .PP
215 .Vb 10
216 \& struct policy_plugin {
217 \& #define SUDO_POLICY_PLUGIN     1
218 \&     unsigned int type; /* always SUDO_POLICY_PLUGIN */
219 \&     unsigned int version; /* always SUDO_API_VERSION */
220 \&     int (*open)(unsigned int version, sudo_conv_t conversation,
221 \&                 sudo_printf_t plugin_printf, char * const settings[],
222 \&                 char * const user_info[], char * const user_env[],
223 \&                 char * const plugin_options[]);
224 \&     void (*close)(int exit_status, int error);
225 \&     int (*show_version)(int verbose);
226 \&     int (*check_policy)(int argc, char * const argv[],
227 \&                         char *env_add[], char **command_info[],
228 \&                         char **argv_out[], char **user_env_out[]);
229 \&     int (*list)(int argc, char * const argv[], int verbose,
230 \&                 const char *list_user);
231 \&     int (*validate)(void);
232 \&     void (*invalidate)(int remove);
233 \&     int (*init_session)(struct passwd *pwd, char **user_env[]);
234 \&     void (*register_hooks)(int version,
235 \&        int (*register_hook)(struct sudo_hook *hook));
236 \&     void (*deregister_hooks)(int version,
237 \&        int (*deregister_hook)(struct sudo_hook *hook));
238 \& };
239 .Ve
240 .PP
241 The policy_plugin struct has the following fields:
242 .IP "type" 4
243 .IX Item "type"
244 The \f(CW\*(C`type\*(C'\fR field should always be set to \s-1SUDO_POLICY_PLUGIN\s0.
245 .IP "version" 4
246 .IX Item "version"
247 The \f(CW\*(C`version\*(C'\fR field should be set to \s-1SUDO_API_VERSION\s0.
248 .Sp
249 This allows \fBsudo\fR to determine the \s-1API\s0 version the plugin was
250 built against.
251 .IP "open" 4
252 .IX Item "open"
253 .Vb 4
254 \& int (*open)(unsigned int version, sudo_conv_t conversation,
255 \&             sudo_printf_t plugin_printf, char * const settings[],
256 \&             char * const user_info[], char * const user_env[],
257 \&             char * const plugin_options[]);
258 .Ve
259 .Sp
260 Returns 1 on success, 0 on failure, \-1 if a general error occurred,
261 or \-2 if there was a usage error.  In the latter case, \fBsudo\fR will
262 print a usage message before it exits.  If an error occurs, the
263 plugin may optionally call the conversation or plugin_printf function
264 with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information
265 to the user.
266 .Sp
267 The function arguments are as follows:
268 .RS 4
269 .IP "version" 4
270 .IX Item "version"
271 The version passed in by \fBsudo\fR allows the plugin to determine the
272 major and minor version number of the plugin \s-1API\s0 supported by
273 \&\fBsudo\fR.
274 .IP "conversation" 4
275 .IX Item "conversation"
276 A pointer to the conversation function that can be used by the
277 plugin to interact with the user (see below).
278 Returns 0 on success and \-1 on failure.
279 .IP "plugin_printf" 4
280 .IX Item "plugin_printf"
281 A pointer to a printf-style function that may be used to display
282 informational or error messages (see below).
283 Returns the number of characters printed on success and \-1 on failure.
284 .IP "settings" 4
285 .IX Item "settings"
286 A vector of user-supplied \fBsudo\fR settings in the form of \*(L"name=value\*(R"
287 strings.  The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer.  These
288 settings correspond to flags the user specified when running \fBsudo\fR.
289 As such, they will only be present when the corresponding flag has
290 been specified on the command line.
291 .Sp
292 When parsing \fIsettings\fR, the plugin should split on the \fBfirst\fR
293 equal sign ('=') since the \fIname\fR field will never include one
294 itself but the \fIvalue\fR might.
295 .RS 4
296 .IP "debug_flags=string" 4
297 .IX Item "debug_flags=string"
298 A comma-separated list of debug flags that correspond to \fBsudo\fR's
299 \&\f(CW\*(C`Debug\*(C'\fR entry in \fI@sysconfdir@/sudo.conf\fR, if there is one.  The
300 flags are passed to the plugin as they appear in \fI@sysconfdir@/sudo.conf\fR.
301 The syntax used by \fBsudo\fR and the \fIsudoers\fR plugin is
302 \&\fIsubsystem\fR@\fIpriority\fR but the plugin is free to use a different
303 format so long as it does not include a command \f(CW\*(C`,\*(C'\fR.
304 .Sp
305 For reference, the priorities supported by the \fBsudo\fR front end and
306 \&\fIsudoers\fR are: \fIcrit\fR, \fIerr\fR, \fIwarn\fR, \fInotice\fR, \fIdiag\fR,
307 \&\fIinfo\fR, \fItrace\fR and \fIdebug\fR.
308 .Sp
309 The following subsystems are defined: \fImain\fR, \fImemory\fR, \fIargs\fR,
310 \&\fIexec\fR, \fIpty\fR, \fIutmp\fR, \fIconv\fR, \fIpcomm\fR, \fIutil\fR, \fIlist\fR,
311 \&\fInetif\fR, \fIaudit\fR, \fIedit\fR, \fIselinux\fR, \fIldap\fR, \fImatch\fR, \fIparser\fR,
312 \&\fIalias\fR, \fIdefaults\fR, \fIauth\fR, \fIenv\fR, \fIlogging\fR, \fInss\fR, \fIrbtree\fR,
313 \&\fIperms\fR, \fIplugin\fR.  The subsystem \fIall\fR includes every subsystem.
314 .Sp
315 There is not currently a way to specify a set of debug flags specific
316 to the plugin\*(--the flags are shared by \fBsudo\fR and the plugin.
317 .IP "debug_level=number" 4
318 .IX Item "debug_level=number"
319 This setting has been deprecated in favor of \fIdebug_flags\fR.
320 .IP "runas_user=string" 4
321 .IX Item "runas_user=string"
322 The user name or uid to to run the command as, if specified via the
323 \&\f(CW\*(C`\-u\*(C'\fR flag.
324 .IP "runas_group=string" 4
325 .IX Item "runas_group=string"
326 The group name or gid to to run the command as, if specified via
327 the \f(CW\*(C`\-g\*(C'\fR flag.
328 .IP "prompt=string" 4
329 .IX Item "prompt=string"
330 The prompt to use when requesting a password, if specified via
331 the \f(CW\*(C`\-p\*(C'\fR flag.
332 .IP "set_home=bool" 4
333 .IX Item "set_home=bool"
334 Set to true if the user specified the \f(CW\*(C`\-H\*(C'\fR flag.  If true, set the
335 \&\f(CW\*(C`HOME\*(C'\fR environment variable to the target user's home directory.
336 .IP "preserve_environment=bool" 4
337 .IX Item "preserve_environment=bool"
338 Set to true if the user specified the \f(CW\*(C`\-E\*(C'\fR flag, indicating that
339 the user wishes to preserve the environment.
340 .IP "run_shell=bool" 4
341 .IX Item "run_shell=bool"
342 Set to true if the user specified the \f(CW\*(C`\-s\*(C'\fR flag, indicating that
343 the user wishes to run a shell.
344 .IP "login_shell=bool" 4
345 .IX Item "login_shell=bool"
346 Set to true if the user specified the \f(CW\*(C`\-i\*(C'\fR flag, indicating that
347 the user wishes to run a login shell.
348 .IP "implied_shell=bool" 4
349 .IX Item "implied_shell=bool"
350 If the user does not specify a program on the command line, \fBsudo\fR
351 will pass the plugin the path to the user's shell and set
352 \&\fIimplied_shell\fR to true.  This allows \fBsudo\fR with no arguments
353 to be used similarly to \fIsu\fR\|(1).  If the plugin does not to support
354 this usage, it may return a value of \-2 from the \f(CW\*(C`check_policy\*(C'\fR
355 function, which will cause \fBsudo\fR to print a usage message and
356 exit.
357 .IP "preserve_groups=bool" 4
358 .IX Item "preserve_groups=bool"
359 Set to true if the user specified the \f(CW\*(C`\-P\*(C'\fR flag, indicating that
360 the user wishes to preserve the group vector instead of setting it
361 based on the runas user.
362 .IP "ignore_ticket=bool" 4
363 .IX Item "ignore_ticket=bool"
364 Set to true if the user specified the \f(CW\*(C`\-k\*(C'\fR flag along with a
365 command, indicating that the user wishes to ignore any cached
366 authentication credentials.
367 .IP "noninteractive=bool" 4
368 .IX Item "noninteractive=bool"
369 Set to true if the user specified the \f(CW\*(C`\-n\*(C'\fR flag, indicating that
370 \&\fBsudo\fR should operate in non-interactive mode.  The plugin may
371 reject a command run in non-interactive mode if user interaction
372 is required.
373 .IP "login_class=string" 4
374 .IX Item "login_class=string"
375 \&\s-1BSD\s0 login class to use when setting resource limits and nice value,
376 if specified by the \f(CW\*(C`\-c\*(C'\fR flag.
377 .IP "selinux_role=string" 4
378 .IX Item "selinux_role=string"
379 SELinux role to use when executing the command, if specified by
380 the \f(CW\*(C`\-r\*(C'\fR flag.
381 .IP "selinux_type=string" 4
382 .IX Item "selinux_type=string"
383 SELinux type to use when executing the command, if specified by
384 the \f(CW\*(C`\-t\*(C'\fR flag.
385 .IP "bsdauth_type=string" 4
386 .IX Item "bsdauth_type=string"
387 Authentication type, if specified by the \f(CW\*(C`\-a\*(C'\fR flag, to use on
388 systems where \s-1BSD\s0 authentication is supported.
389 .IP "network_addrs=list" 4
390 .IX Item "network_addrs=list"
391 A space-separated list of \s-1IP\s0 network addresses and netmasks in the
392 form \*(L"addr/netmask\*(R", e.g. \*(L"192.168.1.2/255.255.255.0\*(R".  The address
393 and netmask pairs may be either IPv4 or IPv6, depending on what the
394 operating system supports.  If the address contains a colon (':'),
395 it is an IPv6 address, else it is IPv4.
396 .IP "progname=string" 4
397 .IX Item "progname=string"
398 The command name that sudo was run as, typically \*(L"sudo\*(R" or \*(L"sudoedit\*(R".
399 .IP "sudoedit=bool" 4
400 .IX Item "sudoedit=bool"
401 Set to true when the \f(CW\*(C`\-e\*(C'\fR flag is is specified or if invoked as
402 \&\fBsudoedit\fR.  The plugin shall substitute an editor into \fIargv\fR
403 in the \fIcheck_policy\fR function or return \f(CW\*(C`\-2\*(C'\fR with a usage error
404 if the plugin does not support \fIsudoedit\fR.  For more information,
405 see the \fIcheck_policy\fR section.
406 .IP "closefrom=number" 4
407 .IX Item "closefrom=number"
408 If specified, the user has requested via the \f(CW\*(C`\-C\*(C'\fR flag that \fBsudo\fR
409 close all files descriptors with a value of \fInumber\fR or higher.
410 The plugin may optionally pass this, or another value, back in the
411 \&\fIcommand_info\fR list.
412 .RE
413 .RS 4
414 .Sp
415 Additional settings may be added in the future so the plugin should
416 silently ignore settings that it does not recognize.
417 .RE
418 .IP "user_info" 4
419 .IX Item "user_info"
420 A vector of information about the user running the command in the form of
421 \&\*(L"name=value\*(R" strings.  The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer.
422 .Sp
423 When parsing \fIuser_info\fR, the plugin should split on the \fBfirst\fR
424 equal sign ('=') since the \fIname\fR field will never include one
425 itself but the \fIvalue\fR might.
426 .RS 4
427 .IP "pid=int" 4
428 .IX Item "pid=int"
429 The process \s-1ID\s0 of the running \fBsudo\fR process.
430 Only available starting with \s-1API\s0 version 1.2
431 .IP "ppid=int" 4
432 .IX Item "ppid=int"
433 The parent process \s-1ID\s0 of the running \fBsudo\fR process.
434 Only available starting with \s-1API\s0 version 1.2
435 .IP "sid=int" 4
436 .IX Item "sid=int"
437 The session \s-1ID\s0 of the running \fBsudo\fR process or 0 if \fBsudo\fR is
438 not part of a \s-1POSIX\s0 job control session.
439 Only available starting with \s-1API\s0 version 1.2
440 .IP "pgid=int" 4
441 .IX Item "pgid=int"
442 The \s-1ID\s0 of the process group that the running \fBsudo\fR process belongs
443 to.
444 Only available starting with \s-1API\s0 version 1.2
445 .IP "tcpgid=int" 4
446 .IX Item "tcpgid=int"
447 The \s-1ID\s0 of the forground process group associated with the terminal
448 device associcated with the \fBsudo\fR process or \-1 if there is no
449 terminal present.
450 Only available starting with \s-1API\s0 version 1.2
451 .IP "user=string" 4
452 .IX Item "user=string"
453 The name of the user invoking \fBsudo\fR.
454 .IP "euid=uid_t" 4
455 .IX Item "euid=uid_t"
456 The effective user \s-1ID\s0 of the user invoking \fBsudo\fR.
457 .IP "uid=uid_t" 4
458 .IX Item "uid=uid_t"
459 The real user \s-1ID\s0 of the user invoking \fBsudo\fR.
460 .IP "egid=gid_t" 4
461 .IX Item "egid=gid_t"
462 The effective group \s-1ID\s0 of the user invoking \fBsudo\fR.
463 .IP "gid=gid_t" 4
464 .IX Item "gid=gid_t"
465 The real group \s-1ID\s0 of the user invoking \fBsudo\fR.
466 .IP "groups=list" 4
467 .IX Item "groups=list"
468 The user's supplementary group list formatted as a string of
469 comma-separated group IDs.
470 .IP "cwd=string" 4
471 .IX Item "cwd=string"
472 The user's current working directory.
473 .IP "tty=string" 4
474 .IX Item "tty=string"
475 The path to the user's terminal device.  If the user has no terminal
476 device associated with the session, the value will be empty, as in
477 \&\f(CW\*(C`tty=\*(C'\fR.
478 .IP "host=string" 4
479 .IX Item "host=string"
480 The local machine's hostname as returned by the \f(CW\*(C`gethostname()\*(C'\fR
481 system call.
482 .IP "lines=int" 4
483 .IX Item "lines=int"
484 The number of lines the user's terminal supports.  If there is
485 no terminal device available, a default value of 24 is used.
486 .IP "cols=int" 4
487 .IX Item "cols=int"
488 The number of columns the user's terminal supports.  If there is
489 no terminal device available, a default value of 80 is used.
490 .RE
491 .RS 4
492 .RE
493 .IP "user_env" 4
494 .IX Item "user_env"
495 The user's environment in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of
496 \&\*(L"name=value\*(R" strings.
497 .Sp
498 When parsing \fIuser_env\fR, the plugin should split on the \fBfirst\fR
499 equal sign ('=') since the \fIname\fR field will never include one
500 itself but the \fIvalue\fR might.
501 .IP "plugin_options" 4
502 .IX Item "plugin_options"
503 Any (non-comment) strings immediately after the plugin path are
504 treated as arguments to the plugin.  These arguments are split on
505 a white space boundary and are passed to the plugin in the form of
506 a \f(CW\*(C`NULL\*(C'\fR\-terminated array of strings.  If no arguments were
507 specified, \fIplugin_options\fR will be the \s-1NULL\s0 pointer.
508 .Sp
509 \&\s-1NOTE:\s0 the \fIplugin_options\fR parameter is only available starting with
510 \&\s-1API\s0 version 1.2.  A plugin \fBmust\fR check the \s-1API\s0 version specified
511 by the \fBsudo\fR front end before using \fIplugin_options\fR.  Failure to
512 do so may result in a crash.
513 .RE
514 .RS 4
515 .RE
516 .IP "close" 4
517 .IX Item "close"
518 .Vb 1
519 \& void (*close)(int exit_status, int error);
520 .Ve
521 .Sp
522 The \f(CW\*(C`close\*(C'\fR function is called when the command being run by \fBsudo\fR
523 finishes.
524 .Sp
525 The function arguments are as follows:
526 .RS 4
527 .IP "exit_status" 4
528 .IX Item "exit_status"
529 The command's exit status, as returned by the \fIwait\fR\|(2) system call.
530 The value of \f(CW\*(C`exit_status\*(C'\fR is undefined if \f(CW\*(C`error\*(C'\fR is non-zero.
531 .IP "error" 4
532 .IX Item "error"
533 If the command could not be executed, this is set to the value of
534 \&\f(CW\*(C`errno\*(C'\fR set by the \fIexecve\fR\|(2) system call.  The plugin is responsible
535 for displaying error information via the conversation or plugin_printf
536 function.  If the command was successfully executed, the value of
537 \&\f(CW\*(C`error\*(C'\fR is 0.
538 .RE
539 .RS 4
540 .RE
541 .IP "show_version" 4
542 .IX Item "show_version"
543 .Vb 1
544 \& int (*show_version)(int verbose);
545 .Ve
546 .Sp
547 The \f(CW\*(C`show_version\*(C'\fR function is called by \fBsudo\fR when the user specifies
548 the \f(CW\*(C`\-V\*(C'\fR option.  The plugin may display its version information
549 to the user via the conversation or plugin_printf function using
550 \&\f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR.  If the user requests detailed version
551 information, the verbose flag will be set.
552 .IP "check_policy" 4
553 .IX Item "check_policy"
554 .Vb 3
555 \& int (*check_policy)(int argc, char * const argv[]
556 \&                     char *env_add[], char **command_info[],
557 \&                     char **argv_out[], char **user_env_out[]);
558 .Ve
559 .Sp
560 The \fIcheck_policy\fR function is called by \fBsudo\fR to determine
561 whether the user is allowed to run the specified commands.
562 .Sp
563 If the \fIsudoedit\fR option was enabled in the \fIsettings\fR array
564 passed to the \fIopen\fR function, the user has requested \fIsudoedit\fR
565 mode.  \fIsudoedit\fR is a mechanism for editing one or more files
566 where an editor is run with the user's credentials instead of with
567 elevated privileges.  \fBsudo\fR achieves this by creating user-writable
568 temporary copies of the files to be edited and then overwriting the
569 originals with the temporary copies after editing is complete.  If
570 the plugin supports \fBsudoedit\fR, it should choose the editor to be
571 used, potentially from a variable in the user's environment, such
572 as \f(CW\*(C`EDITOR\*(C'\fR, and include it in \fIargv_out\fR (note that environment
573 variables may include command line flags).  The files to be edited
574 should be copied from \fIargv\fR into \fIargv_out\fR, separated from the
575 editor and its arguments by a \f(CW"\-\-"\fR element.  The \f(CW"\-\-"\fR will
576 be removed by \fBsudo\fR before the editor is executed.  The plugin
577 should also set \fIsudoedit=true\fR in the \fIcommand_info\fR list.
578 .Sp
579 The \fIcheck_policy\fR function returns 1 if the command is allowed,
580 0 if not allowed, \-1 for a general error, or \-2 for a usage error
581 or if \fBsudoedit\fR was specified but is unsupported by the plugin.
582 In the latter case, \fBsudo\fR will print a usage message before it
583 exits.  If an error occurs, the plugin may optionally call the
584 conversation or plugin_printf function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR
585 to present additional error information to the user.
586 .Sp
587 The function arguments are as follows:
588 .RS 4
589 .IP "argc" 4
590 .IX Item "argc"
591 The number of elements in \fIargv\fR, not counting the final \f(CW\*(C`NULL\*(C'\fR
592 pointer.
593 .IP "argv" 4
594 .IX Item "argv"
595 The argument vector describing the command the user wishes to run,
596 in the same form as what would be passed to the \fIexecve()\fR system
597 call.  The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer.
598 .IP "env_add" 4
599 .IX Item "env_add"
600 Additional environment variables specified by the user on the command
601 line in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of \*(L"name=value\*(R"
602 strings.  The plugin may reject the command if one or more variables
603 are not allowed to be set, or it may silently ignore such variables.
604 .Sp
605 When parsing \fIenv_add\fR, the plugin should split on the \fBfirst\fR
606 equal sign ('=') since the \fIname\fR field will never include one
607 itself but the \fIvalue\fR might.
608 .IP "command_info" 4
609 .IX Item "command_info"
610 Information about the command being run in the form of \*(L"name=value\*(R"
611 strings.  These values are used by \fBsudo\fR to set the execution
612 environment when running a command.  The plugin is responsible for
613 creating and populating the vector, which must be terminated with
614 a \f(CW\*(C`NULL\*(C'\fR pointer.  The following values are recognized by \fBsudo\fR:
615 .RS 4
616 .IP "command=string" 4
617 .IX Item "command=string"
618 Fully qualified path to the command to be executed.
619 .IP "runas_uid=uid" 4
620 .IX Item "runas_uid=uid"
621 User \s-1ID\s0 to run the command as.
622 .IP "runas_euid=uid" 4
623 .IX Item "runas_euid=uid"
624 Effective user \s-1ID\s0 to run the command as.
625 If not specified, the value of \fIrunas_uid\fR is used.
626 .IP "runas_gid=gid" 4
627 .IX Item "runas_gid=gid"
628 Group \s-1ID\s0 to run the command as.
629 .IP "runas_egid=gid" 4
630 .IX Item "runas_egid=gid"
631 Effective group \s-1ID\s0 to run the command as.
632 If not specified, the value of \fIrunas_gid\fR is used.
633 .IP "runas_groups=list" 4
634 .IX Item "runas_groups=list"
635 The supplementary group vector to use for the command in the form
636 of a comma-separated list of group IDs.  If \fIpreserve_groups\fR
637 is set, this option is ignored.
638 .IP "login_class=string" 4
639 .IX Item "login_class=string"
640 \&\s-1BSD\s0 login class to use when setting resource limits and nice value
641 (optional).  This option is only set on systems that support login
642 classes.
643 .IP "preserve_groups=bool" 4
644 .IX Item "preserve_groups=bool"
645 If set, \fBsudo\fR will preserve the user's group vector instead of
646 initializing the group vector based on \f(CW\*(C`runas_user\*(C'\fR.
647 .IP "cwd=string" 4
648 .IX Item "cwd=string"
649 The current working directory to change to when executing the command.
650 .IP "noexec=bool" 4
651 .IX Item "noexec=bool"
652 If set, prevent the command from executing other programs.
653 .IP "chroot=string" 4
654 .IX Item "chroot=string"
655 The root directory to use when running the command.
656 .IP "nice=int" 4
657 .IX Item "nice=int"
658 Nice value (priority) to use when executing the command.  The nice
659 value, if specified, overrides the priority associated with the
660 \&\fIlogin_class\fR on \s-1BSD\s0 systems.
661 .IP "umask=octal" 4
662 .IX Item "umask=octal"
663 The file creation mask to use when executing the command.
664 .IP "selinux_role=string" 4
665 .IX Item "selinux_role=string"
666 SELinux role to use when executing the command.
667 .IP "selinux_type=string" 4
668 .IX Item "selinux_type=string"
669 SELinux type to use when executing the command.
670 .IP "timeout=int" 4
671 .IX Item "timeout=int"
672 Command timeout.  If non-zero then when the timeout expires the
673 command will be killed.
674 .IP "sudoedit=bool" 4
675 .IX Item "sudoedit=bool"
676 Set to true when in \fIsudoedit\fR mode.  The plugin may enable
677 \&\fIsudoedit\fR mode even if \fBsudo\fR was not invoked as \fBsudoedit\fR.
678 This allows the plugin to perform command substitution and transparently
679 enable \fIsudoedit\fR when the user attempts to run an editor.
680 .IP "closefrom=number" 4
681 .IX Item "closefrom=number"
682 If specified, \fBsudo\fR will close all files descriptors with a value
683 of \fInumber\fR or higher.
684 .IP "iolog_compress=bool" 4
685 .IX Item "iolog_compress=bool"
686 Set to true if the I/O logging plugins, if any, should compress the
687 log data.  This is a hint to the I/O logging plugin which may choose
688 to ignore it.
689 .IP "iolog_path=string" 4
690 .IX Item "iolog_path=string"
691 Fully qualified path to the file or directory in which I/O log is
692 to be stored.  This is a hint to the I/O logging plugin which may
693 choose to ignore it.  If no I/O logging plugin is loaded, this
694 setting has no effect.
695 .IP "iolog_stdin=bool" 4
696 .IX Item "iolog_stdin=bool"
697 Set to true if the I/O logging plugins, if any, should log the
698 standard input if it is not connected to a terminal device.  This
699 is a hint to the I/O logging plugin which may choose to ignore it.
700 .IP "iolog_stdout=bool" 4
701 .IX Item "iolog_stdout=bool"
702 Set to true if the I/O logging plugins, if any, should log the
703 standard output if it is not connected to a terminal device.  This
704 is a hint to the I/O logging plugin which may choose to ignore it.
705 .IP "iolog_stderr=bool" 4
706 .IX Item "iolog_stderr=bool"
707 Set to true if the I/O logging plugins, if any, should log the
708 standard error if it is not connected to a terminal device.  This
709 is a hint to the I/O logging plugin which may choose to ignore it.
710 .IP "iolog_ttyin=bool" 4
711 .IX Item "iolog_ttyin=bool"
712 Set to true if the I/O logging plugins, if any, should log all
713 terminal input.  This only includes input typed by the user and not
714 from a pipe or redirected from a file.  This is a hint to the I/O
715 logging plugin which may choose to ignore it.
716 .IP "iolog_ttyout=bool" 4
717 .IX Item "iolog_ttyout=bool"
718 Set to true if the I/O logging plugins, if any, should log all
719 terminal output.  This only includes output to the screen, not
720 output to a pipe or file.  This is a hint to the I/O logging plugin
721 which may choose to ignore it.
722 .IP "use_pty=bool" 4
723 .IX Item "use_pty=bool"
724 Allocate a pseudo-tty to run the command in, regardless of whether
725 or not I/O logging is in use.  By default, \fBsudo\fR will only run
726 the command in a pty when an I/O log plugin is loaded.
727 .IP "set_utmp=bool" 4
728 .IX Item "set_utmp=bool"
729 Create a utmp (or utmpx) entry when a pseudo-tty is allocated.  By
730 default, the new entry will be a copy of the user's existing utmp
731 entry (if any), with the tty, time, type and pid fields updated.
732 .IP "utmp_user=string" 4
733 .IX Item "utmp_user=string"
734 User name to use when constructing a new utmp (or utmpx) entry when
735 \&\fIset_utmp\fR is enabled.  This option can be used to set the user
736 field in the utmp entry to the user the command runs as rather than
737 the invoking user.  If not set, \fBsudo\fR will base the new entry on
738 the invoking user's existing entry.
739 .RE
740 .RS 4
741 .Sp
742 Unsupported values will be ignored.
743 .RE
744 .IP "argv_out" 4
745 .IX Item "argv_out"
746 The \f(CW\*(C`NULL\*(C'\fR\-terminated argument vector to pass to the \fIexecve()\fR
747 system call when executing the command.  The plugin is responsible
748 for allocating and populating the vector.
749 .IP "user_env_out" 4
750 .IX Item "user_env_out"
751 The \f(CW\*(C`NULL\*(C'\fR\-terminated environment vector to use when executing the
752 command.  The plugin is responsible for allocating and populating
753 the vector.
754 .RE
755 .RS 4
756 .RE
757 .IP "list" 4
758 .IX Item "list"
759 .Vb 2
760 \& int (*list)(int verbose, const char *list_user,
761 \&             int argc, char * const argv[]);
762 .Ve
763 .Sp
764 List available privileges for the invoking user.  Returns 1 on
765 success, 0 on failure and \-1 on error.  On error, the plugin may
766 optionally call the conversation or plugin_printf function with
767 \&\f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information to
768 the user.
769 .Sp
770 Privileges should be output via the conversation or plugin_printf
771 function using \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR.
772 .RS 4
773 .IP "verbose" 4
774 .IX Item "verbose"
775 Flag indicating whether to list in verbose mode or not.
776 .IP "list_user" 4
777 .IX Item "list_user"
778 The name of a different user to list privileges for if the policy
779 allows it.  If \f(CW\*(C`NULL\*(C'\fR, the plugin should list the privileges of
780 the invoking user.
781 .IP "argc" 4
782 .IX Item "argc"
783 The number of elements in \fIargv\fR, not counting the final \f(CW\*(C`NULL\*(C'\fR
784 pointer.
785 .IP "argv" 4
786 .IX Item "argv"
787 If non\-\f(CW\*(C`NULL\*(C'\fR, an argument vector describing a command the user
788 wishes to check against the policy in the same form as what would
789 be passed to the \fIexecve()\fR system call.  If the command is permitted
790 by the policy, the fully-qualified path to the command should be
791 displayed along with any command line arguments.
792 .RE
793 .RS 4
794 .RE
795 .IP "validate" 4
796 .IX Item "validate"
797 .Vb 1
798 \& int (*validate)(void);
799 .Ve
800 .Sp
801 The \f(CW\*(C`validate\*(C'\fR function is called when \fBsudo\fR is run with the
802 \&\f(CW\*(C`\-v\*(C'\fR flag.  For policy plugins such as \fIsudoers\fR that cache
803 authentication credentials, this function will validate and cache
804 the credentials.
805 .Sp
806 The \f(CW\*(C`validate\*(C'\fR function should be \f(CW\*(C`NULL\*(C'\fR if the plugin does not
807 support credential caching.
808 .Sp
809 Returns 1 on success, 0 on failure and \-1 on error.
810 On error, the plugin may optionally call the conversation or plugin_printf
811 function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional
812 error information to the user.
813 .IP "invalidate" 4
814 .IX Item "invalidate"
815 .Vb 1
816 \& void (*invalidate)(int remove);
817 .Ve
818 .Sp
819 The \f(CW\*(C`invalidate\*(C'\fR function is called when \fBsudo\fR is called with
820 the \f(CW\*(C`\-k\*(C'\fR or \f(CW\*(C`\-K\*(C'\fR flag.  For policy plugins such as \fIsudoers\fR that
821 cache authentication credentials, this function will invalidate the
822 credentials.  If the \fIremove\fR flag is set, the plugin may remove
823 the credentials instead of simply invalidating them.
824 .Sp
825 The \f(CW\*(C`invalidate\*(C'\fR function should be \f(CW\*(C`NULL\*(C'\fR if the plugin does not
826 support credential caching.
827 .IP "init_session" 4
828 .IX Item "init_session"
829 .Vb 1
830 \& int (*init_session)(struct passwd *pwd, char **user_envp[);
831 .Ve
832 .Sp
833 The \f(CW\*(C`init_session\*(C'\fR function is called before \fBsudo\fR sets up the
834 execution environment for the command.  It is run in the parent
835 \&\fBsudo\fR process and before any uid or gid changes.  This can be used
836 to perform session setup that is not supported by \fIcommand_info\fR,
837 such as opening the \s-1PAM\s0 session.  The \f(CW\*(C`close\*(C'\fR function can be
838 used to tear down the session that was opened by \f(CW\*(C`init_session\*(C'\fR.
839 .Sp
840 The \fIpwd\fR argument points to a passwd struct for the user the
841 command will be run as if the uid the command will run as was found
842 in the password database, otherwise it will be \s-1NULL\s0.
843 .Sp
844 The \fIuser_env\fR argument points to the environment the command will
845 run in, in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of \*(L"name=value\*(R"
846 strings.  This is the same string passed back to the front end via
847 the Policy Plugin's \fIuser_env_out\fR parameter.  If the \f(CW\*(C`init_session\*(C'\fR
848 function needs to modify the user environment, it should update the
849 pointer stored in \fIuser_env\fR.  The expected use case is to merge
850 the contents of the \s-1PAM\s0 environment (if any) with the contents of
851 \&\fIuser_env\fR.  \s-1NOTE:\s0 the \fIuser_env\fR parameter is only available
852 starting with \s-1API\s0 version 1.2.  A plugin \fBmust\fR check the \s-1API\s0
853 version specified by the \fBsudo\fR front end before using \fIuser_env\fR.
854 Failure to do so may result in a crash.
855 .Sp
856 Returns 1 on success, 0 on failure and \-1 on error.
857 On error, the plugin may optionally call the conversation or plugin_printf
858 function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional
859 error information to the user.
860 .IP "register_hooks" 4
861 .IX Item "register_hooks"
862 .Vb 2
863 \& void (*register_hooks)(int version,
864 \&    int (*register_hook)(struct sudo_hook *hook));
865 .Ve
866 .Sp
867 The \f(CW\*(C`register_hooks\*(C'\fR function is called by the sudo front end to
868 register any hooks the plugin needs.  If the plugin does not support
869 hooks, \f(CW\*(C`register_hooks\*(C'\fR should be set to the \s-1NULL\s0 pointer.
870 .Sp
871 The \fIversion\fR argument describes the version of the hooks \s-1API\s0
872 supported by the \fBsudo\fR front end.
873 .Sp
874 The \f(CW\*(C`register_hook\*(C'\fR function should be used to register any supported
875 hooks the plugin needs.  It returns 0 on success, 1 if the hook
876 type is not supported and \-1 if the major version in \f(CW\*(C`struct hook\*(C'\fR
877 does not match the front end's major hook \s-1API\s0 version.
878 .Sp
879 See the \*(L"Hook Function \s-1API\s0\*(R" section below for more information
880 about hooks.
881 .Sp
882 \&\s-1NOTE:\s0 the \f(CW\*(C`register_hooks\*(C'\fR function is only available starting
883 with \s-1API\s0 version 1.2.  If the \fBsudo\fR front end doesn't support \s-1API\s0
884 version 1.2 or higher, \f(CW\*(C`register_hooks\*(C'\fR will not be called.
885 .IP "deregister_hooks" 4
886 .IX Item "deregister_hooks"
887 .Vb 2
888 \& void (*deregister_hooks)(int version,
889 \&    int (*deregister_hook)(struct sudo_hook *hook));
890 .Ve
891 .Sp
892 The \f(CW\*(C`deregister_hooks\*(C'\fR function is called by the sudo front end
893 to deregister any hooks the plugin has registered.  If the plugin
894 does not support hooks, \f(CW\*(C`deregister_hooks\*(C'\fR should be set to the
895 \&\s-1NULL\s0 pointer.
896 .Sp
897 The \fIversion\fR argument describes the version of the hooks \s-1API\s0
898 supported by the \fBsudo\fR front end.
899 .Sp
900 The \f(CW\*(C`deregister_hook\*(C'\fR function should be used to deregister any
901 hooks that were put in place by the \f(CW\*(C`register_hook\*(C'\fR function.  If
902 the plugin tries to deregister a hook that the front end does not
903 support, \f(CW\*(C`deregister_hook\*(C'\fR will return an error.
904 .Sp
905 See the \*(L"Hook Function \s-1API\s0\*(R" section below for more information
906 about hooks.
907 .Sp
908 \&\s-1NOTE:\s0 the \f(CW\*(C`deregister_hooks\*(C'\fR function is only available starting
909 with \s-1API\s0 version 1.2.  If the \fBsudo\fR front end doesn't support \s-1API\s0
910 version 1.2 or higher, \f(CW\*(C`deregister_hooks\*(C'\fR will not be called.
911 .PP
912 \fIPolicy Plugin Version Macros\fR
913 .IX Subsection "Policy Plugin Version Macros"
914 .PP
915 .Vb 6
916 \& /* Plugin API version major/minor. */
917 \& #define SUDO_API_VERSION_MAJOR 1
918 \& #define SUDO_API_VERSION_MINOR 2
919 \& #define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
920 \& #define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR,\e
921 \&                                             SUDO_API_VERSION_MINOR)
922 \&
923 \& /* Getters and setters for API version */
924 \& #define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
925 \& #define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
926 \& #define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \e
927 \&     *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
928 \& } while(0)
929 \& #define SUDO_VERSION_SET_MINOR(vp, n) do { \e
930 \&     *(vp) = (*(vp) & 0xffff0000) | (n); \e
931 \& } while(0)
932 .Ve
933 .SS "I/O Plugin \s-1API\s0"
934 .IX Subsection "I/O Plugin API"
935 .Vb 10
936 \& struct io_plugin {
937 \& #define SUDO_IO_PLUGIN         2
938 \&     unsigned int type; /* always SUDO_IO_PLUGIN */
939 \&     unsigned int version; /* always SUDO_API_VERSION */
940 \&     int (*open)(unsigned int version, sudo_conv_t conversation
941 \&                 sudo_printf_t plugin_printf, char * const settings[],
942 \&                 char * const user_info[], int argc, char * const argv[],
943 \&                 char * const user_env[], char * const plugin_options[]);
944 \&     void (*close)(int exit_status, int error); /* wait status or error */
945 \&     int (*show_version)(int verbose);
946 \&     int (*log_ttyin)(const char *buf, unsigned int len);
947 \&     int (*log_ttyout)(const char *buf, unsigned int len);
948 \&     int (*log_stdin)(const char *buf, unsigned int len);
949 \&     int (*log_stdout)(const char *buf, unsigned int len);
950 \&     int (*log_stderr)(const char *buf, unsigned int len);
951 \&     void (*register_hooks)(int version,
952 \&        int (*register_hook)(struct sudo_hook *hook));
953 \&     void (*deregister_hooks)(int version,
954 \&        int (*deregister_hook)(struct sudo_hook *hook));
955 \& };
956 .Ve
957 .PP
958 When an I/O plugin is loaded, \fBsudo\fR runs the command in a pseudo-tty.
959 This makes it possible to log the input and output from the user's
960 session.  If any of the standard input, standard output or standard
961 error do not correspond to a tty, \fBsudo\fR will open a pipe to capture
962 the I/O for logging before passing it on.
963 .PP
964 The log_ttyin function receives the raw user input from the terminal
965 device (note that this will include input even when echo is disabled,
966 such as when a password is read). The log_ttyout function receives
967 output from the pseudo-tty that is suitable for replaying the user's
968 session at a later time.  The log_stdin, log_stdout and log_stderr
969 functions are only called if the standard input, standard output
970 or standard error respectively correspond to something other than
971 a tty.
972 .PP
973 Any of the logging functions may be set to the \s-1NULL\s0
974 pointer if no logging is to be performed.  If the open function
975 returns \f(CW0\fR, no I/O will be sent to the plugin.
976 .PP
977 The io_plugin struct has the following fields:
978 .IP "type" 4
979 .IX Item "type"
980 The \f(CW\*(C`type\*(C'\fR field should always be set to \s-1SUDO_IO_PLUGIN\s0
981 .IP "version" 4
982 .IX Item "version"
983 The \f(CW\*(C`version\*(C'\fR field should be set to \s-1SUDO_API_VERSION\s0.
984 .Sp
985 This allows \fBsudo\fR to determine the \s-1API\s0 version the plugin was
986 built against.
987 .IP "open" 4
988 .IX Item "open"
989 .Vb 4
990 \& int (*open)(unsigned int version, sudo_conv_t conversation
991 \&             sudo_printf_t plugin_printf, char * const settings[],
992 \&             char * const user_info[], int argc, char * const argv[],
993 \&             char * const user_env[], char * const plugin_options[]);
994 .Ve
995 .Sp
996 The \fIopen\fR function is run before the \fIlog_input\fR, \fIlog_output\fR
997 or \fIshow_version\fR functions are called.  It is only called if the
998 version is being requested or the \fIcheck_policy\fR function has
999 returned successfully.  It returns 1 on success, 0 on failure, \-1
1000 if a general error occurred, or \-2 if there was a usage error.  In
1001 the latter case, \fBsudo\fR will print a usage message before it exits.
1002 If an error occurs, the plugin may optionally call the conversation
1003 or plugin_printf function with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present
1004 additional error information to the user.
1005 .Sp
1006 The function arguments are as follows:
1007 .RS 4
1008 .IP "version" 4
1009 .IX Item "version"
1010 The version passed in by \fBsudo\fR allows the plugin to determine the
1011 major and minor version number of the plugin \s-1API\s0 supported by
1012 \&\fBsudo\fR.
1013 .IP "conversation" 4
1014 .IX Item "conversation"
1015 A pointer to the conversation function that may be used by the
1016 \&\fIshow_version\fR function to display version information (see
1017 show_version below).  The conversation function may also be used
1018 to display additional error message to the user.
1019 The conversation function returns 0 on success and \-1 on failure.
1020 .IP "plugin_printf" 4
1021 .IX Item "plugin_printf"
1022 A pointer to a printf-style function that may be used by the
1023 \&\fIshow_version\fR function to display version information (see
1024 show_version below).  The plugin_printf function may also be used
1025 to display additional error message to the user.
1026 The plugin_printf function returns number of characters printed on
1027 success and \-1 on failure.
1028 .IP "settings" 4
1029 .IX Item "settings"
1030 A vector of user-supplied \fBsudo\fR settings in the form of \*(L"name=value\*(R"
1031 strings.  The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer.  These
1032 settings correspond to flags the user specified when running \fBsudo\fR.
1033 As such, they will only be present when the corresponding flag has
1034 been specified on the command line.
1035 .Sp
1036 When parsing \fIsettings\fR, the plugin should split on the \fBfirst\fR
1037 equal sign ('=') since the \fIname\fR field will never include one
1038 itself but the \fIvalue\fR might.
1039 .Sp
1040 See the \*(L"Policy Plugin \s-1API\s0\*(R" section for a list of all possible settings.
1041 .IP "user_info" 4
1042 .IX Item "user_info"
1043 A vector of information about the user running the command in the form of
1044 \&\*(L"name=value\*(R" strings.  The vector is terminated by a \f(CW\*(C`NULL\*(C'\fR pointer.
1045 .Sp
1046 When parsing \fIuser_info\fR, the plugin should split on the \fBfirst\fR
1047 equal sign ('=') since the \fIname\fR field will never include one
1048 itself but the \fIvalue\fR might.
1049 .Sp
1050 See the \*(L"Policy Plugin \s-1API\s0\*(R" section for a list of all possible strings.
1051 .IP "argc" 4
1052 .IX Item "argc"
1053 The number of elements in \fIargv\fR, not counting the final \f(CW\*(C`NULL\*(C'\fR
1054 pointer.
1055 .IP "argv" 4
1056 .IX Item "argv"
1057 If non\-\f(CW\*(C`NULL\*(C'\fR, an argument vector describing a command the user
1058 wishes to run in the same form as what would be passed to the
1059 \&\fIexecve()\fR system call.
1060 .IP "user_env" 4
1061 .IX Item "user_env"
1062 The user's environment in the form of a \f(CW\*(C`NULL\*(C'\fR\-terminated vector of
1063 \&\*(L"name=value\*(R" strings.
1064 .Sp
1065 When parsing \fIuser_env\fR, the plugin should split on the \fBfirst\fR
1066 equal sign ('=') since the \fIname\fR field will never include one
1067 itself but the \fIvalue\fR might.
1068 .IP "plugin_options" 4
1069 .IX Item "plugin_options"
1070 Any (non-comment) strings immediately after the plugin path are
1071 treated as arguments to the plugin.  These arguments are split on
1072 a white space boundary and are passed to the plugin in the form of
1073 a \f(CW\*(C`NULL\*(C'\fR\-terminated array of strings.  If no arguments were
1074 specified, \fIplugin_options\fR will be the \s-1NULL\s0 pointer.
1075 .Sp
1076 \&\s-1NOTE:\s0 the \fIplugin_options\fR parameter is only available starting with
1077 \&\s-1API\s0 version 1.2.  A plugin \fBmust\fR check the \s-1API\s0 version specified
1078 by the \fBsudo\fR front end before using \fIplugin_options\fR.  Failure to
1079 do so may result in a crash.
1080 .RE
1081 .RS 4
1082 .RE
1083 .IP "close" 4
1084 .IX Item "close"
1085 .Vb 1
1086 \& void (*close)(int exit_status, int error);
1087 .Ve
1088 .Sp
1089 The \f(CW\*(C`close\*(C'\fR function is called when the command being run by \fBsudo\fR
1090 finishes.
1091 .Sp
1092 The function arguments are as follows:
1093 .RS 4
1094 .IP "exit_status" 4
1095 .IX Item "exit_status"
1096 The command's exit status, as returned by the \fIwait\fR\|(2) system call.
1097 The value of \f(CW\*(C`exit_status\*(C'\fR is undefined if \f(CW\*(C`error\*(C'\fR is non-zero.
1098 .IP "error" 4
1099 .IX Item "error"
1100 If the command could not be executed, this is set to the value of
1101 \&\f(CW\*(C`errno\*(C'\fR set by the \fIexecve\fR\|(2) system call.  If the command was
1102 successfully executed, the value of \f(CW\*(C`error\*(C'\fR is 0.
1103 .RE
1104 .RS 4
1105 .RE
1106 .IP "show_version" 4
1107 .IX Item "show_version"
1108 .Vb 1
1109 \& int (*show_version)(int verbose);
1110 .Ve
1111 .Sp
1112 The \f(CW\*(C`show_version\*(C'\fR function is called by \fBsudo\fR when the user specifies
1113 the \f(CW\*(C`\-V\*(C'\fR option.  The plugin may display its version information
1114 to the user via the conversation or plugin_printf function using
1115 \&\f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR.  If the user requests detailed version
1116 information, the verbose flag will be set.
1117 .IP "log_ttyin" 4
1118 .IX Item "log_ttyin"
1119 .Vb 1
1120 \& int (*log_ttyin)(const char *buf, unsigned int len);
1121 .Ve
1122 .Sp
1123 The \fIlog_ttyin\fR function is called whenever data can be read from
1124 the user but before it is passed to the running command.  This
1125 allows the plugin to reject data if it chooses to (for instance
1126 if the input contains banned content).  Returns \f(CW1\fR if the data
1127 should be passed to the command, \f(CW0\fR if the data is rejected
1128 (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error occurred.
1129 .Sp
1130 The function arguments are as follows:
1131 .RS 4
1132 .IP "buf" 4
1133 .IX Item "buf"
1134 The buffer containing user input.
1135 .IP "len" 4
1136 .IX Item "len"
1137 The length of \fIbuf\fR in bytes.
1138 .RE
1139 .RS 4
1140 .RE
1141 .IP "log_ttyout" 4
1142 .IX Item "log_ttyout"
1143 .Vb 1
1144 \& int (*log_ttyout)(const char *buf, unsigned int len);
1145 .Ve
1146 .Sp
1147 The \fIlog_ttyout\fR function is called whenever data can be read from
1148 the command but before it is written to the user's terminal.  This
1149 allows the plugin to reject data if it chooses to (for instance
1150 if the output contains banned content).  Returns \f(CW1\fR if the data
1151 should be passed to the user, \f(CW0\fR if the data is rejected
1152 (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error occurred.
1153 .Sp
1154 The function arguments are as follows:
1155 .RS 4
1156 .IP "buf" 4
1157 .IX Item "buf"
1158 The buffer containing command output.
1159 .IP "len" 4
1160 .IX Item "len"
1161 The length of \fIbuf\fR in bytes.
1162 .RE
1163 .RS 4
1164 .RE
1165 .IP "log_stdin" 4
1166 .IX Item "log_stdin"
1167 .Vb 1
1168 \& int (*log_stdin)(const char *buf, unsigned int len);
1169 .Ve
1170 .Sp
1171 The \fIlog_stdin\fR function is only used if the standard input does
1172 not correspond to a tty device.  It is called whenever data can be
1173 read from the standard input but before it is passed to the running
1174 command.  This allows the plugin to reject data if it chooses to
1175 (for instance if the input contains banned content).  Returns \f(CW1\fR
1176 if the data should be passed to the command, \f(CW0\fR if the data is
1177 rejected (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error
1178 occurred.
1179 .Sp
1180 The function arguments are as follows:
1181 .RS 4
1182 .IP "buf" 4
1183 .IX Item "buf"
1184 The buffer containing user input.
1185 .IP "len" 4
1186 .IX Item "len"
1187 The length of \fIbuf\fR in bytes.
1188 .RE
1189 .RS 4
1190 .RE
1191 .IP "log_stdout" 4
1192 .IX Item "log_stdout"
1193 .Vb 1
1194 \& int (*log_stdout)(const char *buf, unsigned int len);
1195 .Ve
1196 .Sp
1197 The \fIlog_stdout\fR function is only used if the standard output does
1198 not correspond to a tty device.  It is called whenever data can be
1199 read from the command but before it is written to the standard
1200 output.  This allows the plugin to reject data if it chooses to
1201 (for instance if the output contains banned content).  Returns \f(CW1\fR
1202 if the data should be passed to the user, \f(CW0\fR if the data is
1203 rejected (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error
1204 occurred.
1205 .Sp
1206 The function arguments are as follows:
1207 .RS 4
1208 .IP "buf" 4
1209 .IX Item "buf"
1210 The buffer containing command output.
1211 .IP "len" 4
1212 .IX Item "len"
1213 The length of \fIbuf\fR in bytes.
1214 .RE
1215 .RS 4
1216 .RE
1217 .IP "log_stderr" 4
1218 .IX Item "log_stderr"
1219 .Vb 1
1220 \& int (*log_stderr)(const char *buf, unsigned int len);
1221 .Ve
1222 .Sp
1223 The \fIlog_stderr\fR function is only used if the standard error does
1224 not correspond to a tty device.  It is called whenever data can be
1225 read from the command but before it is written to the standard
1226 error.  This allows the plugin to reject data if it chooses to
1227 (for instance if the output contains banned content).  Returns \f(CW1\fR
1228 if the data should be passed to the user, \f(CW0\fR if the data is
1229 rejected (which will terminate the command) or \f(CW\*(C`\-1\*(C'\fR if an error
1230 occurred.
1231 .Sp
1232 The function arguments are as follows:
1233 .RS 4
1234 .IP "buf" 4
1235 .IX Item "buf"
1236 The buffer containing command output.
1237 .IP "len" 4
1238 .IX Item "len"
1239 The length of \fIbuf\fR in bytes.
1240 .RE
1241 .RS 4
1242 .RE
1243 .IP "register_hooks" 4
1244 .IX Item "register_hooks"
1245 See the \*(L"Policy Plugin \s-1API\s0\*(R" section for a description of
1246 \&\f(CW\*(C`register_hooks\*(C'\fR.
1247 .IP "deregister_hooks" 4
1248 .IX Item "deregister_hooks"
1249 See the \*(L"Policy Plugin \s-1API\s0\*(R" section for a description of
1250 \&\f(CW\*(C`deregister_hooks\*(C'\fR.
1251 .PP
1252 \fII/O Plugin Version Macros\fR
1253 .IX Subsection "I/O Plugin Version Macros"
1254 .PP
1255 Same as for the \*(L"Policy Plugin \s-1API\s0\*(R".
1256 .SS "Hook Function \s-1API\s0"
1257 .IX Subsection "Hook Function API"
1258 Beginning with plugin \s-1API\s0 version 1.2, it is possible to install
1259 hooks for certain functions called by the \fBsudo\fR front end.
1260 .PP
1261 Currently, the only supported hooks relate to the handling of
1262 environment variables.  Hooks can be used to intercept attempts to
1263 get, set, or remove environment variables so that these changes can
1264 be reflected in the version of the environment that is used to
1265 execute a command.  A future version of the \s-1API\s0 will support
1266 hooking internal \fBsudo\fR front end functions as well.
1267 .PP
1268 \fIHook structure\fR
1269 .IX Subsection "Hook structure"
1270 .PP
1271 Hooks in \fBsudo\fR are described by the following structure:
1272 .PP
1273 .Vb 1
1274 \& typedef int (*sudo_hook_fn_t)();
1275 \&
1276 \& struct sudo_hook {
1277 \&     int hook_version;
1278 \&     int hook_type;
1279 \&     sudo_hook_fn_t hook_fn;
1280 \&     void *closure;
1281 \& };
1282 .Ve
1283 .PP
1284 The \f(CW\*(C`sudo_hook\*(C'\fR structure has the following fields:
1285 .IP "hook_version" 4
1286 .IX Item "hook_version"
1287 The \f(CW\*(C`hook_version\*(C'\fR field should be set to \s-1SUDO_HOOK_VERSION\s0.
1288 .IP "hook_type" 4
1289 .IX Item "hook_type"
1290 The \f(CW\*(C`hook_type\*(C'\fR field may be one of the following supported hook types:
1291 .RS 4
1292 .IP "\s-1SUDO_HOOK_SETENV\s0" 4
1293 .IX Item "SUDO_HOOK_SETENV"
1294 The C library \f(CW\*(C`setenv()\*(C'\fR function.  Any registered hooks will run
1295 before the C library implementation.  The \f(CW\*(C`hook_fn\*(C'\fR field should
1296 be a function that matches the following typedef:
1297 .Sp
1298 .Vb 2
1299 \& typedef int (*sudo_hook_fn_setenv_t)(const char *name,
1300 \&    const char *value, int overwrite, void *closure);
1301 .Ve
1302 .Sp
1303 If the registered hook does not match the typedef the results are
1304 unspecified.
1305 .IP "\s-1SUDO_HOOK_UNSETENV\s0" 4
1306 .IX Item "SUDO_HOOK_UNSETENV"
1307 The C library \f(CW\*(C`unsetenv()\*(C'\fR function.  Any registered hooks will run
1308 before the C library implementation.  The \f(CW\*(C`hook_fn\*(C'\fR field should
1309 be a function that matches the following typedef:
1310 .Sp
1311 .Vb 2
1312 \& typedef int (*sudo_hook_fn_unsetenv_t)(const char *name,
1313 \&    void *closure);
1314 .Ve
1315 .IP "\s-1SUDO_HOOK_GETENV\s0" 4
1316 .IX Item "SUDO_HOOK_GETENV"
1317 The C library \f(CW\*(C`getenv()\*(C'\fR function.  Any registered hooks will run
1318 before the C library implementation.  The \f(CW\*(C`hook_fn\*(C'\fR field should
1319 be a function that matches the following typedef:
1320 .Sp
1321 .Vb 2
1322 \& typedef int (*sudo_hook_fn_getenv_t)(const char *name,
1323 \&    char **value, void *closure);
1324 .Ve
1325 .Sp
1326 If the registered hook does not match the typedef the results are
1327 unspecified.
1328 .IP "\s-1SUDO_HOOK_PUTENV\s0" 4
1329 .IX Item "SUDO_HOOK_PUTENV"
1330 The C library \f(CW\*(C`putenv()\*(C'\fR function.  Any registered hooks will run
1331 before the C library implementation.  The \f(CW\*(C`hook_fn\*(C'\fR field should
1332 be a function that matches the following typedef:
1333 .Sp
1334 .Vb 2
1335 \& typedef int (*sudo_hook_fn_putenv_t)(char *string,
1336 \&    void *closure);
1337 .Ve
1338 .Sp
1339 If the registered hook does not match the typedef the results are
1340 unspecified.
1341 .RE
1342 .RS 4
1343 .RE
1344 .IP "hook_fn" 4
1345 .IX Item "hook_fn"
1346 .Vb 1
1347 \& sudo_hook_fn_t hook_fn;
1348 .Ve
1349 .Sp
1350 The \f(CW\*(C`hook_fn\*(C'\fR field should be set to the plugin's hook implementation.
1351 The actual function arguments will vary depending on the \f(CW\*(C`hook_type\*(C'\fR
1352 (see \f(CW\*(C`hook_type\*(C'\fR above).  In all cases, the \f(CW\*(C`closure\*(C'\fR field of
1353 \&\f(CW\*(C`struct sudo_hook\*(C'\fR is passed as the last function parameter.  This
1354 can be used to pass arbitrary data to the plugin's hook implementation.
1355 .Sp
1356 The function return value may be one of the following:
1357 .RS 4
1358 .IP "\s-1SUDO_HOOK_RET_ERROR\s0" 4
1359 .IX Item "SUDO_HOOK_RET_ERROR"
1360 The hook function encountered an error.
1361 .IP "\s-1SUDO_HOOK_RET_NEXT\s0" 4
1362 .IX Item "SUDO_HOOK_RET_NEXT"
1363 The hook completed without error, go on to the next hook (including
1364 the native implementation if applicable).  For example, a \f(CW\*(C`getenv\*(C'\fR
1365 hook might return \f(CW\*(C`SUDO_HOOK_RET_NEXT\*(C'\fR if the specified variable
1366 was not found in the private copy of the environment.
1367 .IP "\s-1SUDO_HOOK_RET_STOP\s0" 4
1368 .IX Item "SUDO_HOOK_RET_STOP"
1369 The hook completed without error, stop processing hooks for this
1370 invocation.  This can be used to replace the native implementation.
1371 For example, a \f(CW\*(C`setenv\*(C'\fR hook that operates on a private copy of
1372 the environment but leaves \f(CW\*(C`environ\*(C'\fR unchanged.
1373 .RE
1374 .RS 4
1375 .RE
1376 .PP
1377 Note that it is very easy to create an infinite loop when hooking
1378 C library functions.  For example, a \f(CW\*(C`getenv\*(C'\fR hook that calls the
1379 \&\f(CW\*(C`snprintf\*(C'\fR function may create a loop if the \f(CW\*(C`snprintf\*(C'\fR implementation
1380 calls \f(CW\*(C`getenv\*(C'\fR to check the locale.  To prevent this, you may wish
1381 to use a static variable in the hook function to guard against
1382 nested calls.  E.g.
1383 .PP
1384 .Vb 7
1385 \& static int in_progress = 0; /* avoid recursion */
1386 \& if (in_progress)
1387 \&     return SUDO_HOOK_RET_NEXT;
1388 \& in_progress = 1;
1389 \& ...
1390 \& in_progress = 0;
1391 \& return SUDO_HOOK_RET_STOP;
1392 .Ve
1393 .PP
1394 \fIHook \s-1API\s0 Version Macros\fR
1395 .IX Subsection "Hook API Version Macros"
1396 .PP
1397 .Vb 6
1398 \& /* Hook API version major/minor */
1399 \& #define SUDO_HOOK_VERSION_MAJOR 1
1400 \& #define SUDO_HOOK_VERSION_MINOR 0
1401 \& #define SUDO_HOOK_MKVERSION(x, y) ((x << 16) | y)
1402 \& #define SUDO_HOOK_VERSION SUDO_HOOK_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\e
1403 \&                                               SUDO_HOOK_VERSION_MINOR)
1404 \&
1405 \& /* Getters and setters for hook API version */
1406 \& #define SUDO_HOOK_VERSION_GET_MAJOR(v) ((v) >> 16)
1407 \& #define SUDO_HOOK_VERSION_GET_MINOR(v) ((v) & 0xffff)
1408 \& #define SUDO_HOOK_VERSION_SET_MAJOR(vp, n) do { \e
1409 \&     *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
1410 \& } while(0)
1411 \& #define SUDO_HOOK_VERSION_SET_MINOR(vp, n) do { \e
1412 \&     *(vp) = (*(vp) & 0xffff0000) | (n); \e
1413 \& } while(0)
1414 .Ve
1415 .SS "Conversation \s-1API\s0"
1416 .IX Subsection "Conversation API"
1417 If the plugin needs to interact with the user, it may do so via the
1418 conversation function.  A plugin should not attempt to read directly
1419 from the standard input or the user's tty (neither of which are
1420 guaranteed to exist).  The caller must include a trailing newline
1421 in \f(CW\*(C`msg\*(C'\fR if one is to be printed.
1422 .PP
1423 A printf-style function is also available that can be used to display
1424 informational or error messages to the user, which is usually more
1425 convenient for simple messages where no use input is required.
1426 .PP
1427 .Vb 12
1428 \& struct sudo_conv_message {
1429 \& #define SUDO_CONV_PROMPT_ECHO_OFF  0x0001 /* do not echo user input */
1430 \& #define SUDO_CONV_PROMPT_ECHO_ON   0x0002 /* echo user input */
1431 \& #define SUDO_CONV_ERROR_MSG        0x0003 /* error message */
1432 \& #define SUDO_CONV_INFO_MSG         0x0004 /* informational message */
1433 \& #define SUDO_CONV_PROMPT_MASK      0x0005 /* mask user input */
1434 \& #define SUDO_CONV_DEBUG_MSG        0x0006 /* debugging message */
1435 \& #define SUDO_CONV_PROMPT_ECHO_OK   0x1000 /* flag: allow echo if no tty */
1436 \&     int msg_type;
1437 \&     int timeout;
1438 \&     const char *msg;
1439 \& };
1440 \&
1441 \& struct sudo_conv_reply {
1442 \&     char *reply;
1443 \& };
1444 \&
1445 \& typedef int (*sudo_conv_t)(int num_msgs,
1446 \&              const struct sudo_conv_message msgs[],
1447 \&              struct sudo_conv_reply replies[]);
1448 \&
1449 \& typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
1450 .Ve
1451 .PP
1452 Pointers to the conversation and printf-style functions are passed
1453 in to the plugin's \f(CW\*(C`open\*(C'\fR function when the plugin is initialized.
1454 .PP
1455 To use the conversation function, the plugin must pass an array of
1456 \&\f(CW\*(C`sudo_conv_message\*(C'\fR and \f(CW\*(C`sudo_conv_reply\*(C'\fR structures.  There must
1457 be a \f(CW\*(C`struct sudo_conv_message\*(C'\fR and \f(CW\*(C`struct sudo_conv_reply\*(C'\fR for
1458 each message in the conversation.  The plugin is responsible for
1459 freeing the reply buffer filled in to the \f(CW\*(C`struct sudo_conv_reply\*(C'\fR,
1460 if any.
1461 .PP
1462 The printf-style function uses the same underlying mechanism as the
1463 conversation function but only supports \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR,
1464 \&\f(CW\*(C`SUDO_CONV_ERROR_MSG\*(C'\fR and \f(CW\*(C`SUDO_CONV_DEBUG_MSG\*(C'\fR for the \fImsg_type\fR
1465 parameter.  It can be more convenient than using the conversation
1466 function if no user reply is needed and supports standard \fIprintf()\fR
1467 escape sequences.
1468 .PP
1469 Unlike, \f(CW\*(C`SUDO_CONV_INFO_MSG\*(C'\fR and \f(CW\*(C`SUDO_CONV_ERROR_MSG\*(C'\fR, messages
1470 sent with the <\s-1SUDO_CONV_DEBUG_MSG\s0> \fImsg_type\fR are not directly
1471 user-visible.  Instead, they are logged to the file specified in
1472 the \f(CW\*(C`Debug\*(C'\fR statement (if any) in the \fI@sysconfdir@/sudo.conf\fR
1473 file.  This allows a plugin to log debugging information and is
1474 intended to be used in conjunction with the \fIdebug_flags\fR setting.
1475 .PP
1476 See the sample plugin for an example of the conversation function usage.
1477 .SS "Sudoers Group Plugin \s-1API\s0"
1478 .IX Subsection "Sudoers Group Plugin API"
1479 The \fIsudoers\fR module supports a plugin interface to allow non-Unix
1480 group lookups.  This can be used to query a group source other than
1481 the standard Unix group database.  A sample group plugin is bundled
1482 with \fBsudo\fR that implements file-based lookups.  Third party group
1483 plugins include a \s-1QAS\s0 \s-1AD\s0 plugin available from Quest Software.
1484 .PP
1485 A group plugin must declare and populate a \f(CW\*(C`sudoers_group_plugin\*(C'\fR
1486 struct in the global scope.  This structure contains pointers to
1487 the functions that implement plugin initialization, cleanup and
1488 group lookup.
1489 .PP
1490 .Vb 8
1491 \& struct sudoers_group_plugin {
1492 \&    unsigned int version;
1493 \&    int (*init)(int version, sudo_printf_t sudo_printf,
1494 \&                char *const argv[]);
1495 \&    void (*cleanup)(void);
1496 \&    int (*query)(const char *user, const char *group,
1497 \&                 const struct passwd *pwd);
1498 \&};
1499 .Ve
1500 .PP
1501 The \f(CW\*(C`sudoers_group_plugin\*(C'\fR struct has the following fields:
1502 .IP "version" 4
1503 .IX Item "version"
1504 The \f(CW\*(C`version\*(C'\fR field should be set to \s-1GROUP_API_VERSION\s0.
1505 .Sp
1506 This allows \fIsudoers\fR to determine the \s-1API\s0 version the group plugin
1507 was built against.
1508 .IP "init" 4
1509 .IX Item "init"
1510 .Vb 2
1511 \& int (*init)(int version, sudo_printf_t plugin_printf,
1512 \&             char *const argv[]);
1513 .Ve
1514 .Sp
1515 The \fIinit\fR function is called after \fIsudoers\fR has been parsed but
1516 before any policy checks.  It returns 1 on success, 0 on failure
1517 (or if the plugin is not configured), and \-1 if a error occurred.
1518 If an error occurs, the plugin may call the plugin_printf function
1519 with \f(CW\*(C`SUDO_CONF_ERROR_MSG\*(C'\fR to present additional error information
1520 to the user.
1521 .Sp
1522 The function arguments are as follows:
1523 .RS 4
1524 .IP "version" 4
1525 .IX Item "version"
1526 The version passed in by \fIsudoers\fR allows the plugin to determine the
1527 major and minor version number of the group plugin \s-1API\s0 supported by
1528 \&\fIsudoers\fR.
1529 .IP "plugin_printf" 4
1530 .IX Item "plugin_printf"
1531 A pointer to a printf-style function that may be used to display
1532 informational or error message to the user.
1533 Returns the number of characters printed on success and \-1 on failure.
1534 .IP "argv" 4
1535 .IX Item "argv"
1536 A NULL-terminated array of arguments generated from the \fIgroup_plugin\fR
1537 option in \fIsudoers\fR.  If no arguments were given, \fIargv\fR will be
1538 \&\s-1NULL\s0.
1539 .RE
1540 .RS 4
1541 .RE
1542 .IP "cleanup" 4
1543 .IX Item "cleanup"
1544 .Vb 1
1545 \& void (*cleanup)();
1546 .Ve
1547 .Sp
1548 The \fIcleanup\fR function is called when \fIsudoers\fR has finished its
1549 group checks.  The plugin should free any memory it has allocated
1550 and close open file handles.
1551 .IP "query" 4
1552 .IX Item "query"
1553 .Vb 2
1554 \& int (*query)(const char *user, const char *group,
1555 \&              const struct passwd *pwd);
1556 .Ve
1557 .Sp
1558 The \fIquery\fR function is used to ask the group plugin whether \fIuser\fR
1559 is a member of \fIgroup\fR.
1560 .Sp
1561 The function arguments are as follows:
1562 .RS 4
1563 .IP "user" 4
1564 .IX Item "user"
1565 The name of the user being looked up in the external group database.
1566 .IP "group" 4
1567 .IX Item "group"
1568 The name of the group being queried.
1569 .IP "pwd" 4
1570 .IX Item "pwd"
1571 The password database entry for \fIuser\fR, if any.  If \fIuser\fR is not
1572 present in the password database, \fIpwd\fR will be \f(CW\*(C`NULL\*(C'\fR.
1573 .RE
1574 .RS 4
1575 .RE
1576 .PP
1577 \fIGroup \s-1API\s0 Version Macros\fR
1578 .IX Subsection "Group API Version Macros"
1579 .PP
1580 .Vb 5
1581 \& /* Sudoers group plugin version major/minor */
1582 \& #define GROUP_API_VERSION_MAJOR 1
1583 \& #define GROUP_API_VERSION_MINOR 0
1584 \& #define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \e
1585 \&                            GROUP_API_VERSION_MINOR)
1586 \&
1587 \& /* Getters and setters for group version */
1588 \& #define GROUP_API_VERSION_GET_MAJOR(v) ((v) >> 16)
1589 \& #define GROUP_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
1590 \& #define GROUP_API_VERSION_SET_MAJOR(vp, n) do { \e
1591 \&     *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \e
1592 \& } while(0)
1593 \& #define GROUP_API_VERSION_SET_MINOR(vp, n) do { \e
1594 \&     *(vp) = (*(vp) & 0xffff0000) | (n); \e
1595 \& } while(0)
1596 .Ve
1597 .SH "PLUGIN API CHANGELOG"
1598 .IX Header "PLUGIN API CHANGELOG"
1599 The following revisions have been made to the Sudo Plugin \s-1API\s0.
1600 .IP "Version 1.0" 4
1601 .IX Item "Version 1.0"
1602 Initial \s-1API\s0 version.
1603 .IP "Version 1.1" 4
1604 .IX Item "Version 1.1"
1605 The I/O logging plugin's \f(CW\*(C`open\*(C'\fR function was modified to take the
1606 \&\f(CW\*(C`command_info\*(C'\fR list as an argument.
1607 .IP "Version 1.2" 4
1608 .IX Item "Version 1.2"
1609 The Policy and I/O logging plugins' \f(CW\*(C`open\*(C'\fR functions are now passed
1610 a list of plugin options if any are specified in \fI@sysconfdir@/sudo.conf\fR.
1611 .Sp
1612 A simple hooks \s-1API\s0 has been introduced to allow plugins to hook in to the
1613 system's environment handling functions.
1614 .Sp
1615 The \f(CW\*(C`init_session\*(C'\fR Policy plugin function is now passed a pointer
1616 to the user environment which can be updated as needed.  This can
1617 be used to merge in environment variables stored in the \s-1PAM\s0 handle
1618 before a command is run.
1619 .SH "SEE ALSO"
1620 .IX Header "SEE ALSO"
1621 \&\fIsudoers\fR\|(@mansectform@), \fIsudo\fR\|(@mansectsu@)
1622 .SH "BUGS"
1623 .IX Header "BUGS"
1624 If you feel you have found a bug in \fBsudo\fR, please submit a bug report
1625 at http://www.sudo.ws/sudo/bugs/
1626 .SH "SUPPORT"
1627 .IX Header "SUPPORT"
1628 Limited free support is available via the sudo-workers mailing list,
1629 see http://www.sudo.ws/mailman/listinfo/sudo\-workers to subscribe or
1630 search the archives.
1631 .SH "DISCLAIMER"
1632 .IX Header "DISCLAIMER"
1633 \&\fBsudo\fR is provided ``\s-1AS\s0 \s-1IS\s0'' and any express or implied warranties,
1634 including, but not limited to, the implied warranties of merchantability
1635 and fitness for a particular purpose are disclaimed.  See the \s-1LICENSE\s0
1636 file distributed with \fBsudo\fR or http://www.sudo.ws/sudo/license.html
1637 for complete details.