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