Annotation of embedaddon/sudo/doc/sudo_plugin.pod, revision 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>