Annotation of embedaddon/sudo/doc/sudo_plugin.man.in, revision 1.1.1.2
1.1.1.2 ! misho 1: .\" Copyright (c) 2009-2012 Todd C. Miller <Todd.Miller@courtesan.com>
1.1 misho 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@"
1.1.1.2 ! misho 142: .TH SUDO_PLUGIN @mansectsu@ "April 23, 2012" "1.8.5" "MAINTENANCE COMMANDS"
1.1 misho 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
1.1.1.2 ! misho 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.
1.1 misho 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:
1.1.1.2 ! misho 192: \& # Plugin plugin_name plugin_path plugin_options ...
1.1 misho 193: \& # Path askpass /path/to/askpass
1.1.1.2 ! misho 194: \& # Path noexec /path/to/sudo_noexec.so
! 195: \& # Debug sudo /var/log/sudo_debug all@warn
! 196: \& # Set disable_coredump true
1.1 misho 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.
1.1.1.2 ! misho 202: \& # The plugin_options are optional.
1.1 misho 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[],
1.1.1.2 ! misho 222: \& char * const user_info[], char * const user_env[],
! 223: \& char * const plugin_options[]);
1.1 misho 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);
1.1.1.2 ! misho 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));
1.1 misho 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"
1.1.1.2 ! misho 253: .Vb 4
1.1 misho 254: \& int (*open)(unsigned int version, sudo_conv_t conversation,
255: \& sudo_printf_t plugin_printf, char * const settings[],
1.1.1.2 ! misho 256: \& char * const user_info[], char * const user_env[],
! 257: \& char * const plugin_options[]);
1.1 misho 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
1.1.1.2 ! misho 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.
1.1 misho 317: .IP "debug_level=number" 4
318: .IX Item "debug_level=number"
1.1.1.2 ! misho 319: This setting has been deprecated in favor of \fIdebug_flags\fR.
1.1 misho 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
1.1.1.2 ! misho 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
1.1 misho 451: .IP "user=string" 4
452: .IX Item "user=string"
453: The name of the user invoking \fBsudo\fR.
1.1.1.2 ! misho 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.
1.1 misho 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.
1.1.1.2 ! misho 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.
1.1 misho 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.
1.1.1.2 ! misho 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.
1.1 misho 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
1.1.1.2 ! misho 830: \& int (*init_session)(struct passwd *pwd, char **user_envp[);
1.1 misho 831: .Ve
832: .Sp
1.1.1.2 ! misho 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.
1.1 misho 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
1.1.1.2 ! misho 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
1.1 misho 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.
1.1.1.2 ! misho 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.
1.1 misho 911: .PP
1.1.1.2 ! misho 912: \fIPolicy Plugin Version Macros\fR
! 913: .IX Subsection "Policy Plugin Version Macros"
1.1 misho 914: .PP
1.1.1.2 ! misho 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 */
1.1 misho 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[],
1.1.1.2 ! misho 943: \& char * const user_env[], char * const plugin_options[]);
1.1 misho 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);
1.1.1.2 ! misho 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));
1.1 misho 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[],
1.1.1.2 ! misho 993: \& char * const user_env[], char * const plugin_options[]);
1.1 misho 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.
1.1.1.2 ! misho 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.
1.1 misho 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
1.1.1.2 ! misho 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.
1.1 misho 1251: .PP
1.1.1.2 ! misho 1252: \fII/O Plugin Version Macros\fR
! 1253: .IX Subsection "I/O Plugin Version Macros"
1.1 misho 1254: .PP
1255: Same as for the \*(L"Policy Plugin \s-1API\s0\*(R".
1.1.1.2 ! misho 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
1.1 misho 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
1.1.1.2 ! misho 1427: .Vb 12
1.1 misho 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 */
1.1.1.2 ! misho 1434: \& #define SUDO_CONV_DEBUG_MSG 0x0006 /* debugging message */
1.1 misho 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
1.1.1.2 ! misho 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.
1.1 misho 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
1.1.1.2 ! misho 1577: \fIGroup \s-1API\s0 Version Macros\fR
! 1578: .IX Subsection "Group API Version Macros"
1.1 misho 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
1.1.1.2 ! misho 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.
1.1 misho 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.
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>