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