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