Annotation of embedaddon/sudo/doc/sudo_plugin.pod, revision 1.1.1.1
1.1 misho 1: Copyright (c) 2009-2011 Todd C. Miller <Todd.Miller@courtesan.com>
2:
3: Permission to use, copy, modify, and distribute this software for any
4: purpose with or without fee is hereby granted, provided that the above
5: copyright notice and this permission notice appear in all copies.
6:
7: THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8: WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9: MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10: ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11: WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12: ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13: OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14: ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15:
16: =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
51: parameters after the I<path> are ignored. Lines that don't begin
52: with C<Plugin> or C<Path> are silently ignored.
53:
54: The same shared object may contain multiple plugins, each with a
55: different symbol name. The shared object file must be owned by uid
56: 0 and only writable by its owner. Because of ambiguities that arise
57: from composite policies, only a single policy plugin may be specified.
58: This limitation does not apply to I/O plugins.
59:
60: #
61: # Default @sysconfdir@/sudo.conf file
62: #
63: # Format:
64: # Plugin plugin_name plugin_path
65: # Path askpass /path/to/askpass
66: #
67: # The plugin_path is relative to @prefix@/libexec unless
68: # fully qualified.
69: # The plugin_name corresponds to a global symbol in the plugin
70: # that contains the plugin interface structure.
71: #
72: Plugin sudoers_policy sudoers.so
73: Plugin sudoers_io sudoers.so
74:
75: =head2 Policy Plugin API
76:
77: A policy plugin must declare and populate a C<policy_plugin> struct
78: in the global scope. This structure contains pointers to the functions
79: that implement the B<sudo> policy checks. The name of the symbol should
80: be specified in F<@sysconfdir@/sudo.conf> along with a path to the plugin
81: so that B<sudo> can load it.
82:
83: struct policy_plugin {
84: #define SUDO_POLICY_PLUGIN 1
85: unsigned int type; /* always SUDO_POLICY_PLUGIN */
86: unsigned int version; /* always SUDO_API_VERSION */
87: int (*open)(unsigned int version, sudo_conv_t conversation,
88: sudo_printf_t plugin_printf, char * const settings[],
89: char * const user_info[], char * const user_env[]);
90: void (*close)(int exit_status, int error);
91: int (*show_version)(int verbose);
92: int (*check_policy)(int argc, char * const argv[],
93: char *env_add[], char **command_info[],
94: char **argv_out[], char **user_env_out[]);
95: int (*list)(int argc, char * const argv[], int verbose,
96: const char *list_user);
97: int (*validate)(void);
98: void (*invalidate)(int remove);
99: int (*init_session)(struct passwd *pwd);
100: };
101:
102: The policy_plugin struct has the following fields:
103:
104: =over 4
105:
106: =item type
107:
108: The C<type> field should always be set to SUDO_POLICY_PLUGIN.
109:
110: =item version
111:
112: The C<version> field should be set to SUDO_API_VERSION.
113:
114: This allows B<sudo> to determine the API version the plugin was
115: built against.
116:
117: =item open
118:
119: int (*open)(unsigned int version, sudo_conv_t conversation,
120: sudo_printf_t plugin_printf, char * const settings[],
121: char * const user_info[], char * const user_env[]);
122:
123: Returns 1 on success, 0 on failure, -1 if a general error occurred,
124: or -2 if there was a usage error. In the latter case, B<sudo> will
125: print a usage message before it exits. If an error occurs, the
126: plugin may optionally call the conversation or plugin_printf function
127: with C<SUDO_CONF_ERROR_MSG> to present additional error information
128: to the user.
129:
130: The function arguments are as follows:
131:
132: =over 4
133:
134: =item version
135:
136: The version passed in by B<sudo> allows the plugin to determine the
137: major and minor version number of the plugin API supported by
138: B<sudo>.
139:
140: =item conversation
141:
142: A pointer to the conversation function that can be used by the
143: plugin to interact with the user (see below).
144: Returns 0 on success and -1 on failure.
145:
146: =item plugin_printf
147:
148: A pointer to a printf-style function that may be used to display
149: informational or error messages (see below).
150: Returns the number of characters printed on success and -1 on failure.
151:
152: =item settings
153:
154: A vector of user-supplied B<sudo> settings in the form of "name=value"
155: strings. The vector is terminated by a C<NULL> pointer. These
156: settings correspond to flags the user specified when running B<sudo>.
157: As such, they will only be present when the corresponding flag has
158: been specified on the command line.
159:
160: When parsing I<settings>, the plugin should split on the B<first>
161: equal sign ('=') since the I<name> field will never include one
162: itself but the I<value> might.
163:
164: =over 4
165:
166: =item debug_level=number
167:
168: A numeric debug level, from 1-9, if specified via the C<-D> flag.
169:
170: =item runas_user=string
171:
172: The user name or uid to to run the command as, if specified via the
173: C<-u> flag.
174:
175: =item runas_group=string
176:
177: The group name or gid to to run the command as, if specified via
178: the C<-g> flag.
179:
180: =item prompt=string
181:
182: The prompt to use when requesting a password, if specified via
183: the C<-p> flag.
184:
185: =item set_home=bool
186:
187: Set to true if the user specified the C<-H> flag. If true, set the
188: C<HOME> environment variable to the target user's home directory.
189:
190: =item preserve_environment=bool
191:
192: Set to true if the user specified the C<-E> flag, indicating that
193: the user wishes to preserve the environment.
194:
195: =item run_shell=bool
196:
197: Set to true if the user specified the C<-s> flag, indicating that
198: the user wishes to run a shell.
199:
200: =item login_shell=bool
201:
202: Set to true if the user specified the C<-i> flag, indicating that
203: the user wishes to run a login shell.
204:
205: =item implied_shell=bool
206:
207: If the user does not specify a program on the command line, B<sudo>
208: will pass the plugin the path to the user's shell and set
209: I<implied_shell> to true. This allows B<sudo> with no arguments
210: to be used similarly to L<su(1)>. If the plugin does not to support
211: this usage, it may return a value of -2 from the C<check_policy>
212: function, which will cause B<sudo> to print a usage message and
213: exit.
214:
215: =item preserve_groups=bool
216:
217: Set to true if the user specified the C<-P> flag, indicating that
218: the user wishes to preserve the group vector instead of setting it
219: based on the runas user.
220:
221: =item ignore_ticket=bool
222:
223: Set to true if the user specified the C<-k> flag along with a
224: command, indicating that the user wishes to ignore any cached
225: authentication credentials.
226:
227: =item noninteractive=bool
228:
229: Set to true if the user specified the C<-n> flag, indicating that
230: B<sudo> should operate in non-interactive mode. The plugin may
231: reject a command run in non-interactive mode if user interaction
232: is required.
233:
234: =item login_class=string
235:
236: BSD login class to use when setting resource limits and nice value,
237: if specified by the C<-c> flag.
238:
239: =item selinux_role=string
240:
241: SELinux role to use when executing the command, if specified by
242: the C<-r> flag.
243:
244: =item selinux_type=string
245:
246: SELinux type to use when executing the command, if specified by
247: the C<-t> flag.
248:
249: =item bsdauth_type=string
250:
251: Authentication type, if specified by the C<-a> flag, to use on
252: systems where BSD authentication is supported.
253:
254: =item network_addrs=list
255:
256: A space-separated list of IP network addresses and netmasks in the
257: form "addr/netmask", e.g. "192.168.1.2/255.255.255.0". The address
258: and netmask pairs may be either IPv4 or IPv6, depending on what the
259: operating system supports. If the address contains a colon (':'),
260: it is an IPv6 address, else it is IPv4.
261:
262: =item progname=string
263:
264: The command name that sudo was run as, typically "sudo" or "sudoedit".
265:
266: =item sudoedit=bool
267:
268: Set to true when the C<-e> flag is is specified or if invoked as
269: B<sudoedit>. The plugin shall substitute an editor into I<argv>
270: in the I<check_policy> function or return C<-2> with a usage error
271: if the plugin does not support I<sudoedit>. For more information,
272: see the I<check_policy> section.
273:
274: =item closefrom=number
275:
276: If specified, the user has requested via the C<-C> flag that B<sudo>
277: close all files descriptors with a value of I<number> or higher.
278: The plugin may optionally pass this, or another value, back in the
279: I<command_info> list.
280:
281: =back
282:
283: Additional settings may be added in the future so the plugin should
284: silently ignore settings that it does not recognize.
285:
286: =item user_info
287:
288: A vector of information about the user running the command in the form of
289: "name=value" strings. The vector is terminated by a C<NULL> pointer.
290:
291: When parsing I<user_info>, the plugin should split on the B<first>
292: equal sign ('=') since the I<name> field will never include one
293: itself but the I<value> might.
294:
295: =over 4
296:
297: =item user=string
298:
299: The name of the user invoking B<sudo>.
300:
301: =item uid=uid_t
302:
303: The real user ID of the user invoking B<sudo>.
304:
305: =item gid=gid_t
306:
307: The real group ID of the user invoking B<sudo>.
308:
309: =item groups=list
310:
311: The user's supplementary group list formatted as a string of
312: comma-separated group IDs.
313:
314: =item cwd=string
315:
316: The user's current working directory.
317:
318: =item tty=string
319:
320: The path to the user's terminal device. If the user has no terminal
321: device associated with the session, the value will be empty, as in
322: C<tty=>.
323:
324: =item host=string
325:
326: The local machine's hostname as returned by the C<gethostname()>
327: system call.
328:
329: =item lines=int
330:
331: The number of lines the user's terminal supports. If there is
332: no terminal device available, a default value of 24 is used.
333:
334: =item cols=int
335:
336: The number of columns the user's terminal supports. If there is
337: no terminal device available, a default value of 80 is used.
338:
339: =back
340:
341: =item user_env
342:
343: The user's environment in the form of a C<NULL>-terminated vector of
344: "name=value" strings.
345:
346: When parsing I<user_env>, the plugin should split on the B<first>
347: equal sign ('=') since the I<name> field will never include one
348: itself but the I<value> might.
349:
350: =back
351:
352: =item close
353:
354: void (*close)(int exit_status, int error);
355:
356: The C<close> function is called when the command being run by B<sudo>
357: finishes.
358:
359: The function arguments are as follows:
360:
361: =over 4
362:
363: =item exit_status
364:
365: The command's exit status, as returned by the wait(2) system call.
366: The value of C<exit_status> is undefined if C<error> is non-zero.
367:
368: =item error
369:
370: If the command could not be executed, this is set to the value of
371: C<errno> set by the execve(2) system call. The plugin is responsible
372: for displaying error information via the conversation or plugin_printf
373: function. If the command was successfully executed, the value of
374: C<error> is 0.
375:
376: =back
377:
378: =item show_version
379:
380: int (*show_version)(int verbose);
381:
382: The C<show_version> function is called by B<sudo> when the user specifies
383: the C<-V> option. The plugin may display its version information
384: to the user via the conversation or plugin_printf function using
385: C<SUDO_CONV_INFO_MSG>. If the user requests detailed version
386: information, the verbose flag will be set.
387:
388: =item check_policy
389:
390: int (*check_policy)(int argc, char * const argv[]
391: char *env_add[], char **command_info[],
392: char **argv_out[], char **user_env_out[]);
393:
394: The I<check_policy> function is called by B<sudo> to determine
395: whether the user is allowed to run the specified commands.
396:
397: If the I<sudoedit> option was enabled in the I<settings> array
398: passed to the I<open> function, the user has requested I<sudoedit>
399: mode. I<sudoedit> is a mechanism for editing one or more files
400: where an editor is run with the user's credentials instead of with
401: elevated privileges. B<sudo> achieves this by creating user-writable
402: temporary copies of the files to be edited and then overwriting the
403: originals with the temporary copies after editing is complete. If
404: the plugin supports B<sudoedit>, it should choose the editor to be
405: used, potentially from a variable in the user's environment, such
406: as C<EDITOR>, and include it in I<argv_out> (note that environment
407: variables may include command line flags). The files to be edited
408: should be copied from I<argv> into I<argv_out>, separated from the
409: editor and its arguments by a C<"--"> element. The C<"--"> will
410: be removed by B<sudo> before the editor is executed. The plugin
411: should also set I<sudoedit=true> in the I<command_info> list.
412:
413: The I<check_policy> function returns 1 if the command is allowed,
414: 0 if not allowed, -1 for a general error, or -2 for a usage error
415: or if B<sudoedit> was specified but is unsupported by the plugin.
416: In the latter case, B<sudo> will print a usage message before it
417: exits. If an error occurs, the plugin may optionally call the
418: conversation or plugin_printf function with C<SUDO_CONF_ERROR_MSG>
419: to present additional error information to the user.
420:
421: The function arguments are as follows:
422:
423: =over 4
424:
425: =item argc
426:
427: The number of elements in I<argv>, not counting the final C<NULL>
428: pointer.
429:
430: =item argv
431:
432: The argument vector describing the command the user wishes to run,
433: in the same form as what would be passed to the execve() system
434: call. The vector is terminated by a C<NULL> pointer.
435:
436: =item env_add
437:
438: Additional environment variables specified by the user on the command
439: line in the form of a C<NULL>-terminated vector of "name=value"
440: strings. The plugin may reject the command if one or more variables
441: are not allowed to be set, or it may silently ignore such variables.
442:
443: When parsing I<env_add>, the plugin should split on the B<first>
444: equal sign ('=') since the I<name> field will never include one
445: itself but the I<value> might.
446:
447: =item command_info
448:
449: Information about the command being run in the form of "name=value"
450: strings. These values are used by B<sudo> to set the execution
451: environment when running a command. The plugin is responsible for
452: creating and populating the vector, which must be terminated with
453: a C<NULL> pointer. The following values are recognized by B<sudo>:
454:
455: =over 4
456:
457: =item command=string
458:
459: Fully qualified path to the command to be executed.
460:
461: =item runas_uid=uid
462:
463: User ID to run the command as.
464:
465: =item runas_euid=uid
466:
467: Effective user ID to run the command as.
468: If not specified, the value of I<runas_uid> is used.
469:
470: =item runas_gid=gid
471:
472: Group ID to run the command as.
473:
474: =item runas_egid=gid
475:
476: Effective group ID to run the command as.
477: If not specified, the value of I<runas_gid> is used.
478:
479: =item runas_groups=list
480:
481: The supplementary group vector to use for the command in the form
482: of a comma-separated list of group IDs. If I<preserve_groups>
483: is set, this option is ignored.
484:
485: =item login_class=string
486:
487: BSD login class to use when setting resource limits and nice value
488: (optional). This option is only set on systems that support login
489: classes.
490:
491: =item preserve_groups=bool
492:
493: If set, B<sudo> will preserve the user's group vector instead of
494: initializing the group vector based on C<runas_user>.
495:
496: =item cwd=string
497:
498: The current working directory to change to when executing the command.
499:
500: =item noexec=bool
501:
502: If set, prevent the command from executing other programs.
503:
504: =item chroot=string
505:
506: The root directory to use when running the command.
507:
508: =item nice=int
509:
510: Nice value (priority) to use when executing the command. The nice
511: value, if specified, overrides the priority associated with the
512: I<login_class> on BSD systems.
513:
514: =item umask=octal
515:
516: The file creation mask to use when executing the command.
517:
518: =item selinux_role=string
519:
520: SELinux role to use when executing the command.
521:
522: =item selinux_type=string
523:
524: SELinux type to use when executing the command.
525:
526: =item timeout=int
527:
528: Command timeout. If non-zero then when the timeout expires the
529: command will be killed.
530:
531: =item sudoedit=bool
532:
533: Set to true when in I<sudoedit> mode. The plugin may enable
534: I<sudoedit> mode even if B<sudo> was not invoked as B<sudoedit>.
535: This allows the plugin to perform command substitution and transparently
536: enable I<sudoedit> when the user attempts to run an editor.
537:
538: =item closefrom=number
539:
540: If specified, B<sudo> will close all files descriptors with a value
541: of I<number> or higher.
542:
543: =item iolog_compress=bool
544:
545: Set to true if the I/O logging plugins, if any, should compress the
546: log data. This is a hint to the I/O logging plugin which may choose
547: to ignore it.
548:
549: =item iolog_path=string
550:
551: Fully qualified path to the file or directory in which I/O log is
552: to be stored. This is a hint to the I/O logging plugin which may
553: choose to ignore it. If no I/O logging plugin is loaded, this
554: setting has no effect.
555:
556: =item iolog_stdin=bool
557:
558: Set to true if the I/O logging plugins, if any, should log the
559: standard input if it is not connected to a terminal device. This
560: is a hint to the I/O logging plugin which may choose to ignore it.
561:
562: =item iolog_stdout=bool
563:
564: Set to true if the I/O logging plugins, if any, should log the
565: standard output if it is not connected to a terminal device. This
566: is a hint to the I/O logging plugin which may choose to ignore it.
567:
568: =item iolog_stderr=bool
569:
570: Set to true if the I/O logging plugins, if any, should log the
571: standard error if it is not connected to a terminal device. This
572: is a hint to the I/O logging plugin which may choose to ignore it.
573:
574: =item iolog_ttyin=bool
575:
576: Set to true if the I/O logging plugins, if any, should log all
577: terminal input. This only includes input typed by the user and not
578: from a pipe or redirected from a file. This is a hint to the I/O
579: logging plugin which may choose to ignore it.
580:
581: =item iolog_ttyout=bool
582:
583: Set to true if the I/O logging plugins, if any, should log all
584: terminal output. This only includes output to the screen, not
585: output to a pipe or file. This is a hint to the I/O logging plugin
586: which may choose to ignore it.
587:
588: =item use_pty=bool
589:
590: Allocate a pseudo-tty to run the command in, regardless of whether
591: or not I/O logging is in use. By default, B<sudo> will only run
592: the command in a pty when an I/O log plugin is loaded.
593:
594: =item set_utmp=bool
595:
596: Create a utmp (or utmpx) entry when a pseudo-tty is allocated. By
597: default, the new entry will be a copy of the user's existing utmp
598: entry (if any), with the tty, time, type and pid fields updated.
599:
600: =item utmp_user=string
601:
602: User name to use when constructing a new utmp (or utmpx) entry when
603: I<set_utmp> is enabled. This option can be used to set the user
604: field in the utmp entry to the user the command runs as rather than
605: the invoking user. If not set, B<sudo> will base the new entry on
606: the invoking user's existing entry.
607:
608: =back
609:
610: Unsupported values will be ignored.
611:
612: =item argv_out
613:
614: The C<NULL>-terminated argument vector to pass to the execve()
615: system call when executing the command. The plugin is responsible
616: for allocating and populating the vector.
617:
618: =item user_env_out
619:
620: The C<NULL>-terminated environment vector to use when executing the
621: command. The plugin is responsible for allocating and populating
622: the vector.
623:
624: =back
625:
626: =item list
627:
628: int (*list)(int verbose, const char *list_user,
629: int argc, char * const argv[]);
630:
631: List available privileges for the invoking user. Returns 1 on
632: success, 0 on failure and -1 on error. On error, the plugin may
633: optionally call the conversation or plugin_printf function with
634: C<SUDO_CONF_ERROR_MSG> to present additional error information to
635: the user.
636:
637: Privileges should be output via the conversation or plugin_printf
638: function using C<SUDO_CONV_INFO_MSG>.
639:
640: =over 4
641:
642: =item verbose
643:
644: Flag indicating whether to list in verbose mode or not.
645:
646: =item list_user
647:
648: The name of a different user to list privileges for if the policy
649: allows it. If C<NULL>, the plugin should list the privileges of
650: the invoking user.
651:
652: =item argc
653:
654: The number of elements in I<argv>, not counting the final C<NULL>
655: pointer.
656:
657: =item argv
658:
659: If non-C<NULL>, an argument vector describing a command the user
660: wishes to check against the policy in the same form as what would
661: be passed to the execve() system call. If the command is permitted
662: by the policy, the fully-qualified path to the command should be
663: displayed along with any command line arguments.
664:
665: =back
666:
667: =item validate
668:
669: int (*validate)(void);
670:
671: The C<validate> function is called when B<sudo> is run with the
672: C<-v> flag. For policy plugins such as I<sudoers> that cache
673: authentication credentials, this function will validate and cache
674: the credentials.
675:
676: The C<validate> function should be C<NULL> if the plugin does not
677: support credential caching.
678:
679: Returns 1 on success, 0 on failure and -1 on error.
680: On error, the plugin may optionally call the conversation or plugin_printf
681: function with C<SUDO_CONF_ERROR_MSG> to present additional
682: error information to the user.
683:
684: =item invalidate
685:
686: void (*invalidate)(int remove);
687:
688: The C<invalidate> function is called when B<sudo> is called with
689: the C<-k> or C<-K> flag. For policy plugins such as I<sudoers> that
690: cache authentication credentials, this function will invalidate the
691: credentials. If the I<remove> flag is set, the plugin may remove
692: the credentials instead of simply invalidating them.
693:
694: The C<invalidate> function should be C<NULL> if the plugin does not
695: support credential caching.
696:
697: =item init_session
698:
699: int (*init_session)(struct passwd *pwd);
700:
701: The C<init_session> function is called when B<sudo> sets up the
702: execution environment for the command, immediately before the
703: contents of the I<command_info> list are applied (before the uid
704: changes). This can be used to do session setup that is not supported
705: by I<command_info>, such as opening the PAM session.
706:
707: The I<pwd> argument points to a passwd struct for the user the
708: command will be run as if the uid the command will run as was found
709: in the password database, otherwise it will be NULL.
710:
711: Returns 1 on success, 0 on failure and -1 on error.
712: On error, the plugin may optionally call the conversation or plugin_printf
713: function with C<SUDO_CONF_ERROR_MSG> to present additional
714: error information to the user.
715:
716: =back
717:
718: =head3 Version macros
719:
720: #define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
721: #define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
722: #define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \
723: *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
724: } while(0)
725: #define SUDO_VERSION_SET_MINOR(vp, n) do { \
726: *(vp) = (*(vp) & 0xffff0000) | (n); \
727: } while(0)
728:
729: #define SUDO_API_VERSION_MAJOR 1
730: #define SUDO_API_VERSION_MINOR 0
731: #define SUDO_API_VERSION ((SUDO_API_VERSION_MAJOR << 16) | \
732: SUDO_API_VERSION_MINOR)
733:
734: =head2 I/O Plugin API
735:
736: struct io_plugin {
737: #define SUDO_IO_PLUGIN 2
738: unsigned int type; /* always SUDO_IO_PLUGIN */
739: unsigned int version; /* always SUDO_API_VERSION */
740: int (*open)(unsigned int version, sudo_conv_t conversation
741: sudo_printf_t plugin_printf, char * const settings[],
742: char * const user_info[], int argc, char * const argv[],
743: char * const user_env[]);
744: void (*close)(int exit_status, int error); /* wait status or error */
745: int (*show_version)(int verbose);
746: int (*log_ttyin)(const char *buf, unsigned int len);
747: int (*log_ttyout)(const char *buf, unsigned int len);
748: int (*log_stdin)(const char *buf, unsigned int len);
749: int (*log_stdout)(const char *buf, unsigned int len);
750: int (*log_stderr)(const char *buf, unsigned int len);
751: };
752:
753: When an I/O plugin is loaded, B<sudo> runs the command in a pseudo-tty.
754: This makes it possible to log the input and output from the user's
755: session. If any of the standard input, standard output or standard
756: error do not correspond to a tty, B<sudo> will open a pipe to capture
757: the I/O for logging before passing it on.
758:
759: The log_ttyin function receives the raw user input from the terminal
760: device (note that this will include input even when echo is disabled,
761: such as when a password is read). The log_ttyout function receives
762: output from the pseudo-tty that is suitable for replaying the user's
763: session at a later time. The log_stdin, log_stdout and log_stderr
764: functions are only called if the standard input, standard output
765: or standard error respectively correspond to something other than
766: a tty.
767:
768: Any of the logging functions may be set to the NULL
769: pointer if no logging is to be performed. If the open function
770: returns C<0>, no I/O will be sent to the plugin.
771:
772: The io_plugin struct has the following fields:
773:
774: =over 4
775:
776: =item type
777:
778: The C<type> field should always be set to SUDO_IO_PLUGIN
779:
780: =item version
781:
782: The C<version> field should be set to SUDO_API_VERSION.
783:
784: This allows B<sudo> to determine the API version the plugin was
785: built against.
786:
787: =item open
788:
789: int (*open)(unsigned int version, sudo_conv_t conversation
790: sudo_printf_t plugin_printf, char * const settings[],
791: char * const user_info[], int argc, char * const argv[],
792: char * const user_env[]);
793:
794: The I<open> function is run before the I<log_input>, I<log_output>
795: or I<show_version> functions are called. It is only called if the
796: version is being requested or the I<check_policy> function has
797: returned successfully. It returns 1 on success, 0 on failure, -1
798: if a general error occurred, or -2 if there was a usage error. In
799: the latter case, B<sudo> will print a usage message before it exits.
800: If an error occurs, the plugin may optionally call the conversation
801: or plugin_printf function with C<SUDO_CONF_ERROR_MSG> to present
802: additional error information to the user.
803:
804: The function arguments are as follows:
805:
806: =over 4
807:
808: =item version
809:
810: The version passed in by B<sudo> allows the plugin to determine the
811: major and minor version number of the plugin API supported by
812: B<sudo>.
813:
814: =item conversation
815:
816: A pointer to the conversation function that may be used by the
817: I<show_version> function to display version information (see
818: show_version below). The conversation function may also be used
819: to display additional error message to the user.
820: The conversation function returns 0 on success and -1 on failure.
821:
822: =item plugin_printf
823:
824: A pointer to a printf-style function that may be used by the
825: I<show_version> function to display version information (see
826: show_version below). The plugin_printf function may also be used
827: to display additional error message to the user.
828: The plugin_printf function returns number of characters printed on
829: success and -1 on failure.
830:
831: =item settings
832:
833: A vector of user-supplied B<sudo> settings in the form of "name=value"
834: strings. The vector is terminated by a C<NULL> pointer. These
835: settings correspond to flags the user specified when running B<sudo>.
836: As such, they will only be present when the corresponding flag has
837: been specified on the command line.
838:
839: When parsing I<settings>, the plugin should split on the B<first>
840: equal sign ('=') since the I<name> field will never include one
841: itself but the I<value> might.
842:
843: See the L<Policy Plugin API> section for a list of all possible settings.
844:
845: =item user_info
846:
847: A vector of information about the user running the command in the form of
848: "name=value" strings. The vector is terminated by a C<NULL> pointer.
849:
850: When parsing I<user_info>, the plugin should split on the B<first>
851: equal sign ('=') since the I<name> field will never include one
852: itself but the I<value> might.
853:
854: See the L<Policy Plugin API> section for a list of all possible strings.
855:
856: =item argc
857:
858: The number of elements in I<argv>, not counting the final C<NULL>
859: pointer.
860:
861: =item argv
862:
863: If non-C<NULL>, an argument vector describing a command the user
864: wishes to run in the same form as what would be passed to the
865: execve() system call.
866:
867: =item user_env
868:
869: The user's environment in the form of a C<NULL>-terminated vector of
870: "name=value" strings.
871:
872: When parsing I<user_env>, the plugin should split on the B<first>
873: equal sign ('=') since the I<name> field will never include one
874: itself but the I<value> might.
875:
876: =back
877:
878: =item close
879:
880: void (*close)(int exit_status, int error);
881:
882: The C<close> function is called when the command being run by B<sudo>
883: finishes.
884:
885: The function arguments are as follows:
886:
887: =over 4
888:
889: =item exit_status
890:
891: The command's exit status, as returned by the wait(2) system call.
892: The value of C<exit_status> is undefined if C<error> is non-zero.
893:
894: =item error
895:
896: If the command could not be executed, this is set to the value of
897: C<errno> set by the execve(2) system call. If the command was
898: successfully executed, the value of C<error> is 0.
899:
900: =back
901:
902: =item show_version
903:
904: int (*show_version)(int verbose);
905:
906: The C<show_version> function is called by B<sudo> when the user specifies
907: the C<-V> option. The plugin may display its version information
908: to the user via the conversation or plugin_printf function using
909: C<SUDO_CONV_INFO_MSG>. If the user requests detailed version
910: information, the verbose flag will be set.
911:
912: =item log_ttyin
913:
914: int (*log_ttyin)(const char *buf, unsigned int len);
915:
916: The I<log_ttyin> function is called whenever data can be read from
917: the user but before it is passed to the running command. This
918: allows the plugin to reject data if it chooses to (for instance
919: if the input contains banned content). Returns C<1> if the data
920: should be passed to the command, C<0> if the data is rejected
921: (which will terminate the command) or C<-1> if an error occurred.
922:
923: The function arguments are as follows:
924:
925: =over 4
926:
927: =item buf
928:
929: The buffer containing user input.
930:
931: =item len
932:
933: The length of I<buf> in bytes.
934:
935: =back
936:
937: =item log_ttyout
938:
939: int (*log_ttyout)(const char *buf, unsigned int len);
940:
941: The I<log_ttyout> function is called whenever data can be read from
942: the command but before it is written to the user's terminal. This
943: allows the plugin to reject data if it chooses to (for instance
944: if the output contains banned content). Returns C<1> if the data
945: should be passed to the user, C<0> if the data is rejected
946: (which will terminate the command) or C<-1> if an error occurred.
947:
948: The function arguments are as follows:
949:
950: =over 4
951:
952: =item buf
953:
954: The buffer containing command output.
955:
956: =item len
957:
958: The length of I<buf> in bytes.
959:
960: =back
961:
962: =item log_stdin
963:
964: int (*log_stdin)(const char *buf, unsigned int len);
965:
966: The I<log_stdin> function is only used if the standard input does
967: not correspond to a tty device. It is called whenever data can be
968: read from the standard input but before it is passed to the running
969: command. This allows the plugin to reject data if it chooses to
970: (for instance if the input contains banned content). Returns C<1>
971: if the data should be passed to the command, C<0> if the data is
972: rejected (which will terminate the command) or C<-1> if an error
973: occurred.
974:
975: The function arguments are as follows:
976:
977: =over 4
978:
979: =item buf
980:
981: The buffer containing user input.
982:
983: =item len
984:
985: The length of I<buf> in bytes.
986:
987: =back
988:
989: =item log_stdout
990:
991: int (*log_stdout)(const char *buf, unsigned int len);
992:
993: The I<log_stdout> function is only used if the standard output does
994: not correspond to a tty device. It is called whenever data can be
995: read from the command but before it is written to the standard
996: output. This allows the plugin to reject data if it chooses to
997: (for instance if the output contains banned content). Returns C<1>
998: if the data should be passed to the user, C<0> if the data is
999: rejected (which will terminate the command) or C<-1> if an error
1000: occurred.
1001:
1002: The function arguments are as follows:
1003:
1004: =over 4
1005:
1006: =item buf
1007:
1008: The buffer containing command output.
1009:
1010: =item len
1011:
1012: The length of I<buf> in bytes.
1013:
1014: =back
1015:
1016: =item log_stderr
1017:
1018: int (*log_stderr)(const char *buf, unsigned int len);
1019:
1020: The I<log_stderr> function is only used if the standard error does
1021: not correspond to a tty device. It is called whenever data can be
1022: read from the command but before it is written to the standard
1023: error. This allows the plugin to reject data if it chooses to
1024: (for instance if the output contains banned content). Returns C<1>
1025: if the data should be passed to the user, C<0> if the data is
1026: rejected (which will terminate the command) or C<-1> if an error
1027: occurred.
1028:
1029: The function arguments are as follows:
1030:
1031: =over 4
1032:
1033: =item buf
1034:
1035: The buffer containing command output.
1036:
1037: =item len
1038:
1039: The length of I<buf> in bytes.
1040:
1041: =back
1042:
1043: =back
1044:
1045: =head3 Version macros
1046:
1047: Same as for the L<Policy Plugin API>.
1048:
1049: =head2 Conversation API
1050:
1051: If the plugin needs to interact with the user, it may do so via the
1052: conversation function. A plugin should not attempt to read directly
1053: from the standard input or the user's tty (neither of which are
1054: guaranteed to exist). The caller must include a trailing newline
1055: in C<msg> if one is to be printed.
1056:
1057: A printf-style function is also available that can be used to display
1058: informational or error messages to the user, which is usually more
1059: convenient for simple messages where no use input is required.
1060:
1061: struct sudo_conv_message {
1062: #define SUDO_CONV_PROMPT_ECHO_OFF 0x0001 /* do not echo user input */
1063: #define SUDO_CONV_PROMPT_ECHO_ON 0x0002 /* echo user input */
1064: #define SUDO_CONV_ERROR_MSG 0x0003 /* error message */
1065: #define SUDO_CONV_INFO_MSG 0x0004 /* informational message */
1066: #define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */
1067: #define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */
1068: int msg_type;
1069: int timeout;
1070: const char *msg;
1071: };
1072:
1073: struct sudo_conv_reply {
1074: char *reply;
1075: };
1076:
1077: typedef int (*sudo_conv_t)(int num_msgs,
1078: const struct sudo_conv_message msgs[],
1079: struct sudo_conv_reply replies[]);
1080:
1081: typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
1082:
1083: Pointers to the conversation and printf-style functions are passed
1084: in to the plugin's C<open> function when the plugin is initialized.
1085:
1086: To use the conversation function, the plugin must pass an array of
1087: C<sudo_conv_message> and C<sudo_conv_reply> structures. There must
1088: be a C<struct sudo_conv_message> and C<struct sudo_conv_reply> for
1089: each message in the conversation. The plugin is responsible for
1090: freeing the reply buffer filled in to the C<struct sudo_conv_reply>,
1091: if any.
1092:
1093: The printf-style function uses the same underlying mechanism as the
1094: conversation function but only supports C<SUDO_CONV_INFO_MSG> and
1095: C<SUDO_CONV_ERROR_MSG> for the I<msg_type> parameter. It can be
1096: more convenient than using the conversation function if no user
1097: reply is needed and supports standard printf() escape sequences.
1098:
1099: See the sample plugin for an example of the conversation function usage.
1100:
1101: =head2 Sudoers Group Plugin API
1102:
1103: The I<sudoers> module supports a plugin interface to allow non-Unix
1104: group lookups. This can be used to query a group source other than
1105: the standard Unix group database. A sample group plugin is bundled
1106: with B<sudo> that implements file-based lookups. Third party group
1107: plugins include a QAS AD plugin available from Quest Software.
1108:
1109: A group plugin must declare and populate a C<sudoers_group_plugin>
1110: struct in the global scope. This structure contains pointers to
1111: the functions that implement plugin initialization, cleanup and
1112: group lookup.
1113:
1114: struct sudoers_group_plugin {
1115: unsigned int version;
1116: int (*init)(int version, sudo_printf_t sudo_printf,
1117: char *const argv[]);
1118: void (*cleanup)(void);
1119: int (*query)(const char *user, const char *group,
1120: const struct passwd *pwd);
1121: };
1122:
1123: The C<sudoers_group_plugin> struct has the following fields:
1124:
1125: =over 4
1126:
1127: =item version
1128:
1129: The C<version> field should be set to GROUP_API_VERSION.
1130:
1131: This allows I<sudoers> to determine the API version the group plugin
1132: was built against.
1133:
1134: =item init
1135:
1136: int (*init)(int version, sudo_printf_t plugin_printf,
1137: char *const argv[]);
1138:
1139: The I<init> function is called after I<sudoers> has been parsed but
1140: before any policy checks. It returns 1 on success, 0 on failure
1141: (or if the plugin is not configured), and -1 if a error occurred.
1142: If an error occurs, the plugin may call the plugin_printf function
1143: with C<SUDO_CONF_ERROR_MSG> to present additional error information
1144: to the user.
1145:
1146: The function arguments are as follows:
1147:
1148: =over 4
1149:
1150: =item version
1151:
1152: The version passed in by I<sudoers> allows the plugin to determine the
1153: major and minor version number of the group plugin API supported by
1154: I<sudoers>.
1155:
1156: =item plugin_printf
1157:
1158: A pointer to a printf-style function that may be used to display
1159: informational or error message to the user.
1160: Returns the number of characters printed on success and -1 on failure.
1161:
1162: =item argv
1163:
1164: A NULL-terminated array of arguments generated from the I<group_plugin>
1165: option in I<sudoers>. If no arguments were given, I<argv> will be
1166: NULL.
1167:
1168: =back
1169:
1170: =item cleanup
1171:
1172: void (*cleanup)();
1173:
1174: The I<cleanup> function is called when I<sudoers> has finished its
1175: group checks. The plugin should free any memory it has allocated
1176: and close open file handles.
1177:
1178: =item query
1179:
1180: int (*query)(const char *user, const char *group,
1181: const struct passwd *pwd);
1182:
1183: The I<query> function is used to ask the group plugin whether I<user>
1184: is a member of I<group>.
1185:
1186: The function arguments are as follows:
1187:
1188: =over 4
1189:
1190: =item user
1191:
1192: The name of the user being looked up in the external group database.
1193:
1194: =item group
1195:
1196: The name of the group being queried.
1197:
1198: =item pwd
1199:
1200: The password database entry for I<user>, if any. If I<user> is not
1201: present in the password database, I<pwd> will be C<NULL>.
1202:
1203: =back
1204:
1205: =back
1206:
1207: =head3 Version Macros
1208:
1209: /* Sudoers group plugin version major/minor */
1210: #define GROUP_API_VERSION_MAJOR 1
1211: #define GROUP_API_VERSION_MINOR 0
1212: #define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \
1213: GROUP_API_VERSION_MINOR)
1214:
1215: /* Getters and setters for group version */
1216: #define GROUP_API_VERSION_GET_MAJOR(v) ((v) >> 16)
1217: #define GROUP_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
1218: #define GROUP_API_VERSION_SET_MAJOR(vp, n) do { \
1219: *(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
1220: } while(0)
1221: #define GROUP_API_VERSION_SET_MINOR(vp, n) do { \
1222: *(vp) = (*(vp) & 0xffff0000) | (n); \
1223: } while(0)
1224:
1225: =head1 SEE ALSO
1226:
1227: L<sudoers(5)>, L<sudo(8)>
1228:
1229: =head1 BUGS
1230:
1231: If you feel you have found a bug in B<sudo>, please submit a bug report
1232: at http://www.sudo.ws/sudo/bugs/
1233:
1234: =head1 SUPPORT
1235:
1236: Limited free support is available via the sudo-workers mailing list,
1237: see http://www.sudo.ws/mailman/listinfo/sudo-workers to subscribe or
1238: search the archives.
1239:
1240: =head1 DISCLAIMER
1241:
1242: B<sudo> is provided ``AS IS'' and any express or implied warranties,
1243: including, but not limited to, the implied warranties of merchantability
1244: and fitness for a particular purpose are disclaimed. See the LICENSE
1245: file distributed with B<sudo> or http://www.sudo.ws/sudo/license.html
1246: for complete details.
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>