1
Copyright (c) 2009-2012 Todd C. Miller <Todd.Miller@courtesan.com>
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.
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.
20
sudo_plugin - Sudo Plugin API
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.
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.
37
The plugin API is defined by the C<sudo_plugin.h> header file.
39
=head2 The sudo.conf File
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.
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 passed as options to the plugin's
52
I<open> function. Lines that don't begin with C<Plugin>, C<Path>,
53
C<Debug> or C<Set> are silently ignored.
55
The same shared object may contain multiple plugins, each with a
56
different symbol name. The shared object file must be owned by uid
57
0 and only writable by its owner. Because of ambiguities that arise
58
from composite policies, only a single policy plugin may be specified.
59
This limitation does not apply to I/O plugins.
62
# Default @sysconfdir@/sudo.conf file
65
# Plugin plugin_name plugin_path plugin_options ...
66
# Path askpass /path/to/askpass
67
# Path noexec /path/to/sudo_noexec.so
68
# Debug sudo /var/log/sudo_debug all@warn
69
# Set disable_coredump true
71
# The plugin_path is relative to @prefix@/libexec unless
73
# The plugin_name corresponds to a global symbol in the plugin
74
# that contains the plugin interface structure.
75
# The plugin_options are optional.
77
Plugin sudoers_policy sudoers.so
78
Plugin sudoers_io sudoers.so
80
=head2 Policy Plugin API
82
A policy plugin must declare and populate a C<policy_plugin> struct
83
in the global scope. This structure contains pointers to the functions
84
that implement the B<sudo> policy checks. The name of the symbol should
85
be specified in F<@sysconfdir@/sudo.conf> along with a path to the plugin
86
so that B<sudo> can load it.
88
struct policy_plugin {
89
#define SUDO_POLICY_PLUGIN 1
90
unsigned int type; /* always SUDO_POLICY_PLUGIN */
91
unsigned int version; /* always SUDO_API_VERSION */
92
int (*open)(unsigned int version, sudo_conv_t conversation,
93
sudo_printf_t plugin_printf, char * const settings[],
94
char * const user_info[], char * const user_env[],
95
char * const plugin_options[]);
96
void (*close)(int exit_status, int error);
97
int (*show_version)(int verbose);
98
int (*check_policy)(int argc, char * const argv[],
99
char *env_add[], char **command_info[],
100
char **argv_out[], char **user_env_out[]);
101
int (*list)(int argc, char * const argv[], int verbose,
102
const char *list_user);
103
int (*validate)(void);
104
void (*invalidate)(int remove);
105
int (*init_session)(struct passwd *pwd, char **user_env[]);
106
void (*register_hooks)(int version,
107
int (*register_hook)(struct sudo_hook *hook));
108
void (*deregister_hooks)(int version,
109
int (*deregister_hook)(struct sudo_hook *hook));
112
The policy_plugin struct has the following fields:
118
The C<type> field should always be set to SUDO_POLICY_PLUGIN.
122
The C<version> field should be set to SUDO_API_VERSION.
124
This allows B<sudo> to determine the API version the plugin was
129
int (*open)(unsigned int version, sudo_conv_t conversation,
130
sudo_printf_t plugin_printf, char * const settings[],
131
char * const user_info[], char * const user_env[],
132
char * const plugin_options[]);
134
Returns 1 on success, 0 on failure, -1 if a general error occurred,
135
or -2 if there was a usage error. In the latter case, B<sudo> will
136
print a usage message before it exits. If an error occurs, the
137
plugin may optionally call the conversation or plugin_printf function
138
with C<SUDO_CONF_ERROR_MSG> to present additional error information
141
The function arguments are as follows:
147
The version passed in by B<sudo> allows the plugin to determine the
148
major and minor version number of the plugin API supported by
153
A pointer to the conversation function that can be used by the
154
plugin to interact with the user (see below).
155
Returns 0 on success and -1 on failure.
159
A pointer to a printf-style function that may be used to display
160
informational or error messages (see below).
161
Returns the number of characters printed on success and -1 on failure.
165
A vector of user-supplied B<sudo> settings in the form of "name=value"
166
strings. The vector is terminated by a C<NULL> pointer. These
167
settings correspond to flags the user specified when running B<sudo>.
168
As such, they will only be present when the corresponding flag has
169
been specified on the command line.
171
When parsing I<settings>, the plugin should split on the B<first>
172
equal sign ('=') since the I<name> field will never include one
173
itself but the I<value> might.
177
=item debug_flags=string
179
A comma-separated list of debug flags that correspond to B<sudo>'s
180
C<Debug> entry in F<@sysconfdir@/sudo.conf>, if there is one. The
181
flags are passed to the plugin as they appear in F<@sysconfdir@/sudo.conf>.
182
The syntax used by B<sudo> and the I<sudoers> plugin is
183
I<subsystem>@I<priority> but the plugin is free to use a different
184
format so long as it does not include a command C<,>.
186
For reference, the priorities supported by the B<sudo> front end and
187
I<sudoers> are: I<crit>, I<err>, I<warn>, I<notice>, I<diag>,
188
I<info>, I<trace> and I<debug>.
190
The following subsystems are defined: I<main>, I<memory>, I<args>,
191
I<exec>, I<pty>, I<utmp>, I<conv>, I<pcomm>, I<util>, I<list>,
192
I<netif>, I<audit>, I<edit>, I<selinux>, I<ldap>, I<match>, I<parser>,
193
I<alias>, I<defaults>, I<auth>, I<env>, I<logging>, I<nss>, I<rbtree>,
194
I<perms>, I<plugin>. The subsystem I<all> includes every subsystem.
196
There is not currently a way to specify a set of debug flags specific
197
to the plugin--the flags are shared by B<sudo> and the plugin.
199
=item debug_level=number
201
This setting has been deprecated in favor of I<debug_flags>.
203
=item runas_user=string
205
The user name or uid to to run the command as, if specified via the
208
=item runas_group=string
210
The group name or gid to to run the command as, if specified via
215
The prompt to use when requesting a password, if specified via
220
Set to true if the user specified the C<-H> flag. If true, set the
221
C<HOME> environment variable to the target user's home directory.
223
=item preserve_environment=bool
225
Set to true if the user specified the C<-E> flag, indicating that
226
the user wishes to preserve the environment.
230
Set to true if the user specified the C<-s> flag, indicating that
231
the user wishes to run a shell.
233
=item login_shell=bool
235
Set to true if the user specified the C<-i> flag, indicating that
236
the user wishes to run a login shell.
238
=item implied_shell=bool
240
If the user does not specify a program on the command line, B<sudo>
241
will pass the plugin the path to the user's shell and set
242
I<implied_shell> to true. This allows B<sudo> with no arguments
243
to be used similarly to L<su(1)>. If the plugin does not to support
244
this usage, it may return a value of -2 from the C<check_policy>
245
function, which will cause B<sudo> to print a usage message and
248
=item preserve_groups=bool
250
Set to true if the user specified the C<-P> flag, indicating that
251
the user wishes to preserve the group vector instead of setting it
252
based on the runas user.
254
=item ignore_ticket=bool
256
Set to true if the user specified the C<-k> flag along with a
257
command, indicating that the user wishes to ignore any cached
258
authentication credentials.
260
=item noninteractive=bool
262
Set to true if the user specified the C<-n> flag, indicating that
263
B<sudo> should operate in non-interactive mode. The plugin may
264
reject a command run in non-interactive mode if user interaction
267
=item login_class=string
269
BSD login class to use when setting resource limits and nice value,
270
if specified by the C<-c> flag.
272
=item selinux_role=string
274
SELinux role to use when executing the command, if specified by
277
=item selinux_type=string
279
SELinux type to use when executing the command, if specified by
282
=item bsdauth_type=string
284
Authentication type, if specified by the C<-a> flag, to use on
285
systems where BSD authentication is supported.
287
=item network_addrs=list
289
A space-separated list of IP network addresses and netmasks in the
290
form "addr/netmask", e.g. "192.168.1.2/255.255.255.0". The address
291
and netmask pairs may be either IPv4 or IPv6, depending on what the
292
operating system supports. If the address contains a colon (':'),
293
it is an IPv6 address, else it is IPv4.
295
=item progname=string
297
The command name that sudo was run as, typically "sudo" or "sudoedit".
301
Set to true when the C<-e> flag is is specified or if invoked as
302
B<sudoedit>. The plugin shall substitute an editor into I<argv>
303
in the I<check_policy> function or return C<-2> with a usage error
304
if the plugin does not support I<sudoedit>. For more information,
305
see the I<check_policy> section.
307
=item closefrom=number
309
If specified, the user has requested via the C<-C> flag that B<sudo>
310
close all files descriptors with a value of I<number> or higher.
311
The plugin may optionally pass this, or another value, back in the
312
I<command_info> list.
316
Additional settings may be added in the future so the plugin should
317
silently ignore settings that it does not recognize.
321
A vector of information about the user running the command in the form of
322
"name=value" strings. The vector is terminated by a C<NULL> pointer.
324
When parsing I<user_info>, the plugin should split on the B<first>
325
equal sign ('=') since the I<name> field will never include one
326
itself but the I<value> might.
332
The process ID of the running B<sudo> process.
333
Only available starting with API version 1.2
337
The parent process ID of the running B<sudo> process.
338
Only available starting with API version 1.2
342
The session ID of the running B<sudo> process or 0 if B<sudo> is
343
not part of a POSIX job control session.
344
Only available starting with API version 1.2
348
The ID of the process group that the running B<sudo> process belongs
350
Only available starting with API version 1.2
354
The ID of the forground process group associated with the terminal
355
device associcated with the B<sudo> process or -1 if there is no
357
Only available starting with API version 1.2
361
The name of the user invoking B<sudo>.
365
The effective user ID of the user invoking B<sudo>.
369
The real user ID of the user invoking B<sudo>.
373
The effective group ID of the user invoking B<sudo>.
377
The real group ID of the user invoking B<sudo>.
381
The user's supplementary group list formatted as a string of
382
comma-separated group IDs.
386
The user's current working directory.
390
The path to the user's terminal device. If the user has no terminal
391
device associated with the session, the value will be empty, as in
396
The local machine's hostname as returned by the C<gethostname()>
401
The number of lines the user's terminal supports. If there is
402
no terminal device available, a default value of 24 is used.
406
The number of columns the user's terminal supports. If there is
407
no terminal device available, a default value of 80 is used.
413
The user's environment in the form of a C<NULL>-terminated vector of
414
"name=value" strings.
416
When parsing I<user_env>, the plugin should split on the B<first>
417
equal sign ('=') since the I<name> field will never include one
418
itself but the I<value> might.
422
Any (non-comment) strings immediately after the plugin path are
423
treated as arguments to the plugin. These arguments are split on
424
a white space boundary and are passed to the plugin in the form of
425
a C<NULL>-terminated array of strings. If no arguments were
426
specified, I<plugin_options> will be the NULL pointer.
428
NOTE: the I<plugin_options> parameter is only available starting with
429
API version 1.2. A plugin B<must> check the API version specified
430
by the B<sudo> front end before using I<plugin_options>. Failure to
431
do so may result in a crash.
437
void (*close)(int exit_status, int error);
439
The C<close> function is called when the command being run by B<sudo>
442
The function arguments are as follows:
448
The command's exit status, as returned by the wait(2) system call.
449
The value of C<exit_status> is undefined if C<error> is non-zero.
453
If the command could not be executed, this is set to the value of
454
C<errno> set by the execve(2) system call. The plugin is responsible
455
for displaying error information via the conversation or plugin_printf
456
function. If the command was successfully executed, the value of
463
int (*show_version)(int verbose);
465
The C<show_version> function is called by B<sudo> when the user specifies
466
the C<-V> option. The plugin may display its version information
467
to the user via the conversation or plugin_printf function using
468
C<SUDO_CONV_INFO_MSG>. If the user requests detailed version
469
information, the verbose flag will be set.
473
int (*check_policy)(int argc, char * const argv[]
474
char *env_add[], char **command_info[],
475
char **argv_out[], char **user_env_out[]);
477
The I<check_policy> function is called by B<sudo> to determine
478
whether the user is allowed to run the specified commands.
480
If the I<sudoedit> option was enabled in the I<settings> array
481
passed to the I<open> function, the user has requested I<sudoedit>
482
mode. I<sudoedit> is a mechanism for editing one or more files
483
where an editor is run with the user's credentials instead of with
484
elevated privileges. B<sudo> achieves this by creating user-writable
485
temporary copies of the files to be edited and then overwriting the
486
originals with the temporary copies after editing is complete. If
487
the plugin supports B<sudoedit>, it should choose the editor to be
488
used, potentially from a variable in the user's environment, such
489
as C<EDITOR>, and include it in I<argv_out> (note that environment
490
variables may include command line flags). The files to be edited
491
should be copied from I<argv> into I<argv_out>, separated from the
492
editor and its arguments by a C<"--"> element. The C<"--"> will
493
be removed by B<sudo> before the editor is executed. The plugin
494
should also set I<sudoedit=true> in the I<command_info> list.
496
The I<check_policy> function returns 1 if the command is allowed,
497
0 if not allowed, -1 for a general error, or -2 for a usage error
498
or if B<sudoedit> was specified but is unsupported by the plugin.
499
In the latter case, B<sudo> will print a usage message before it
500
exits. If an error occurs, the plugin may optionally call the
501
conversation or plugin_printf function with C<SUDO_CONF_ERROR_MSG>
502
to present additional error information to the user.
504
The function arguments are as follows:
510
The number of elements in I<argv>, not counting the final C<NULL>
515
The argument vector describing the command the user wishes to run,
516
in the same form as what would be passed to the execve() system
517
call. The vector is terminated by a C<NULL> pointer.
521
Additional environment variables specified by the user on the command
522
line in the form of a C<NULL>-terminated vector of "name=value"
523
strings. The plugin may reject the command if one or more variables
524
are not allowed to be set, or it may silently ignore such variables.
526
When parsing I<env_add>, the plugin should split on the B<first>
527
equal sign ('=') since the I<name> field will never include one
528
itself but the I<value> might.
532
Information about the command being run in the form of "name=value"
533
strings. These values are used by B<sudo> to set the execution
534
environment when running a command. The plugin is responsible for
535
creating and populating the vector, which must be terminated with
536
a C<NULL> pointer. The following values are recognized by B<sudo>:
542
Fully qualified path to the command to be executed.
546
User ID to run the command as.
550
Effective user ID to run the command as.
551
If not specified, the value of I<runas_uid> is used.
555
Group ID to run the command as.
559
Effective group ID to run the command as.
560
If not specified, the value of I<runas_gid> is used.
562
=item runas_groups=list
564
The supplementary group vector to use for the command in the form
565
of a comma-separated list of group IDs. If I<preserve_groups>
566
is set, this option is ignored.
568
=item login_class=string
570
BSD login class to use when setting resource limits and nice value
571
(optional). This option is only set on systems that support login
574
=item preserve_groups=bool
576
If set, B<sudo> will preserve the user's group vector instead of
577
initializing the group vector based on C<runas_user>.
581
The current working directory to change to when executing the command.
585
If set, prevent the command from executing other programs.
589
The root directory to use when running the command.
593
Nice value (priority) to use when executing the command. The nice
594
value, if specified, overrides the priority associated with the
595
I<login_class> on BSD systems.
599
The file creation mask to use when executing the command.
601
=item selinux_role=string
603
SELinux role to use when executing the command.
605
=item selinux_type=string
607
SELinux type to use when executing the command.
611
Command timeout. If non-zero then when the timeout expires the
612
command will be killed.
616
Set to true when in I<sudoedit> mode. The plugin may enable
617
I<sudoedit> mode even if B<sudo> was not invoked as B<sudoedit>.
618
This allows the plugin to perform command substitution and transparently
619
enable I<sudoedit> when the user attempts to run an editor.
621
=item closefrom=number
623
If specified, B<sudo> will close all files descriptors with a value
624
of I<number> or higher.
626
=item iolog_compress=bool
628
Set to true if the I/O logging plugins, if any, should compress the
629
log data. This is a hint to the I/O logging plugin which may choose
632
=item iolog_path=string
634
Fully qualified path to the file or directory in which I/O log is
635
to be stored. This is a hint to the I/O logging plugin which may
636
choose to ignore it. If no I/O logging plugin is loaded, this
637
setting has no effect.
639
=item iolog_stdin=bool
641
Set to true if the I/O logging plugins, if any, should log the
642
standard input if it is not connected to a terminal device. This
643
is a hint to the I/O logging plugin which may choose to ignore it.
645
=item iolog_stdout=bool
647
Set to true if the I/O logging plugins, if any, should log the
648
standard output if it is not connected to a terminal device. This
649
is a hint to the I/O logging plugin which may choose to ignore it.
651
=item iolog_stderr=bool
653
Set to true if the I/O logging plugins, if any, should log the
654
standard error if it is not connected to a terminal device. This
655
is a hint to the I/O logging plugin which may choose to ignore it.
657
=item iolog_ttyin=bool
659
Set to true if the I/O logging plugins, if any, should log all
660
terminal input. This only includes input typed by the user and not
661
from a pipe or redirected from a file. This is a hint to the I/O
662
logging plugin which may choose to ignore it.
664
=item iolog_ttyout=bool
666
Set to true if the I/O logging plugins, if any, should log all
667
terminal output. This only includes output to the screen, not
668
output to a pipe or file. This is a hint to the I/O logging plugin
669
which may choose to ignore it.
673
Allocate a pseudo-tty to run the command in, regardless of whether
674
or not I/O logging is in use. By default, B<sudo> will only run
675
the command in a pty when an I/O log plugin is loaded.
679
Create a utmp (or utmpx) entry when a pseudo-tty is allocated. By
680
default, the new entry will be a copy of the user's existing utmp
681
entry (if any), with the tty, time, type and pid fields updated.
683
=item utmp_user=string
685
User name to use when constructing a new utmp (or utmpx) entry when
686
I<set_utmp> is enabled. This option can be used to set the user
687
field in the utmp entry to the user the command runs as rather than
688
the invoking user. If not set, B<sudo> will base the new entry on
689
the invoking user's existing entry.
693
Unsupported values will be ignored.
697
The C<NULL>-terminated argument vector to pass to the execve()
698
system call when executing the command. The plugin is responsible
699
for allocating and populating the vector.
703
The C<NULL>-terminated environment vector to use when executing the
704
command. The plugin is responsible for allocating and populating
711
int (*list)(int verbose, const char *list_user,
712
int argc, char * const argv[]);
714
List available privileges for the invoking user. Returns 1 on
715
success, 0 on failure and -1 on error. On error, the plugin may
716
optionally call the conversation or plugin_printf function with
717
C<SUDO_CONF_ERROR_MSG> to present additional error information to
720
Privileges should be output via the conversation or plugin_printf
721
function using C<SUDO_CONV_INFO_MSG>.
727
Flag indicating whether to list in verbose mode or not.
731
The name of a different user to list privileges for if the policy
732
allows it. If C<NULL>, the plugin should list the privileges of
737
The number of elements in I<argv>, not counting the final C<NULL>
742
If non-C<NULL>, an argument vector describing a command the user
743
wishes to check against the policy in the same form as what would
744
be passed to the execve() system call. If the command is permitted
745
by the policy, the fully-qualified path to the command should be
746
displayed along with any command line arguments.
752
int (*validate)(void);
754
The C<validate> function is called when B<sudo> is run with the
755
C<-v> flag. For policy plugins such as I<sudoers> that cache
756
authentication credentials, this function will validate and cache
759
The C<validate> function should be C<NULL> if the plugin does not
760
support credential caching.
762
Returns 1 on success, 0 on failure and -1 on error.
763
On error, the plugin may optionally call the conversation or plugin_printf
764
function with C<SUDO_CONF_ERROR_MSG> to present additional
765
error information to the user.
769
void (*invalidate)(int remove);
771
The C<invalidate> function is called when B<sudo> is called with
772
the C<-k> or C<-K> flag. For policy plugins such as I<sudoers> that
773
cache authentication credentials, this function will invalidate the
774
credentials. If the I<remove> flag is set, the plugin may remove
775
the credentials instead of simply invalidating them.
777
The C<invalidate> function should be C<NULL> if the plugin does not
778
support credential caching.
782
int (*init_session)(struct passwd *pwd, char **user_envp[);
784
The C<init_session> function is called before B<sudo> sets up the
785
execution environment for the command. It is run in the parent
786
B<sudo> process and before any uid or gid changes. This can be used
787
to perform session setup that is not supported by I<command_info>,
788
such as opening the PAM session. The C<close> function can be
789
used to tear down the session that was opened by C<init_session>.
791
The I<pwd> argument points to a passwd struct for the user the
792
command will be run as if the uid the command will run as was found
793
in the password database, otherwise it will be NULL.
795
The I<user_env> argument points to the environment the command will
796
run in, in the form of a C<NULL>-terminated vector of "name=value"
797
strings. This is the same string passed back to the front end via
798
the Policy Plugin's I<user_env_out> parameter. If the C<init_session>
799
function needs to modify the user environment, it should update the
800
pointer stored in I<user_env>. The expected use case is to merge
801
the contents of the PAM environment (if any) with the contents of
802
I<user_env>. NOTE: the I<user_env> parameter is only available
803
starting with API version 1.2. A plugin B<must> check the API
804
version specified by the B<sudo> front end before using I<user_env>.
805
Failure to do so may result in a crash.
807
Returns 1 on success, 0 on failure and -1 on error.
808
On error, the plugin may optionally call the conversation or plugin_printf
809
function with C<SUDO_CONF_ERROR_MSG> to present additional
810
error information to the user.
814
void (*register_hooks)(int version,
815
int (*register_hook)(struct sudo_hook *hook));
817
The C<register_hooks> function is called by the sudo front end to
818
register any hooks the plugin needs. If the plugin does not support
819
hooks, C<register_hooks> should be set to the NULL pointer.
821
The I<version> argument describes the version of the hooks API
822
supported by the B<sudo> front end.
824
The C<register_hook> function should be used to register any supported
825
hooks the plugin needs. It returns 0 on success, 1 if the hook
826
type is not supported and -1 if the major version in C<struct hook>
827
does not match the front end's major hook API version.
829
See the L<Hook Function API> section below for more information
832
NOTE: the C<register_hooks> function is only available starting
833
with API version 1.2. If the B<sudo> front end doesn't support API
834
version 1.2 or higher, C<register_hooks> will not be called.
836
=item deregister_hooks
838
void (*deregister_hooks)(int version,
839
int (*deregister_hook)(struct sudo_hook *hook));
841
The C<deregister_hooks> function is called by the sudo front end
842
to deregister any hooks the plugin has registered. If the plugin
843
does not support hooks, C<deregister_hooks> should be set to the
846
The I<version> argument describes the version of the hooks API
847
supported by the B<sudo> front end.
849
The C<deregister_hook> function should be used to deregister any
850
hooks that were put in place by the C<register_hook> function. If
851
the plugin tries to deregister a hook that the front end does not
852
support, C<deregister_hook> will return an error.
854
See the L<Hook Function API> section below for more information
857
NOTE: the C<deregister_hooks> function is only available starting
858
with API version 1.2. If the B<sudo> front end doesn't support API
859
version 1.2 or higher, C<deregister_hooks> will not be called.
863
=head3 Policy Plugin Version Macros
865
/* Plugin API version major/minor. */
866
#define SUDO_API_VERSION_MAJOR 1
867
#define SUDO_API_VERSION_MINOR 2
868
#define SUDO_API_MKVERSION(x, y) ((x << 16) | y)
869
#define SUDO_API_VERSION SUDO_API_MKVERSION(SUDO_API_VERSION_MAJOR,\
870
SUDO_API_VERSION_MINOR)
872
/* Getters and setters for API version */
873
#define SUDO_API_VERSION_GET_MAJOR(v) ((v) >> 16)
874
#define SUDO_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
875
#define SUDO_API_VERSION_SET_MAJOR(vp, n) do { \
876
*(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
878
#define SUDO_VERSION_SET_MINOR(vp, n) do { \
879
*(vp) = (*(vp) & 0xffff0000) | (n); \
882
=head2 I/O Plugin API
885
#define SUDO_IO_PLUGIN 2
886
unsigned int type; /* always SUDO_IO_PLUGIN */
887
unsigned int version; /* always SUDO_API_VERSION */
888
int (*open)(unsigned int version, sudo_conv_t conversation
889
sudo_printf_t plugin_printf, char * const settings[],
890
char * const user_info[], int argc, char * const argv[],
891
char * const user_env[], char * const plugin_options[]);
892
void (*close)(int exit_status, int error); /* wait status or error */
893
int (*show_version)(int verbose);
894
int (*log_ttyin)(const char *buf, unsigned int len);
895
int (*log_ttyout)(const char *buf, unsigned int len);
896
int (*log_stdin)(const char *buf, unsigned int len);
897
int (*log_stdout)(const char *buf, unsigned int len);
898
int (*log_stderr)(const char *buf, unsigned int len);
899
void (*register_hooks)(int version,
900
int (*register_hook)(struct sudo_hook *hook));
901
void (*deregister_hooks)(int version,
902
int (*deregister_hook)(struct sudo_hook *hook));
905
When an I/O plugin is loaded, B<sudo> runs the command in a pseudo-tty.
906
This makes it possible to log the input and output from the user's
907
session. If any of the standard input, standard output or standard
908
error do not correspond to a tty, B<sudo> will open a pipe to capture
909
the I/O for logging before passing it on.
911
The log_ttyin function receives the raw user input from the terminal
912
device (note that this will include input even when echo is disabled,
913
such as when a password is read). The log_ttyout function receives
914
output from the pseudo-tty that is suitable for replaying the user's
915
session at a later time. The log_stdin, log_stdout and log_stderr
916
functions are only called if the standard input, standard output
917
or standard error respectively correspond to something other than
920
Any of the logging functions may be set to the NULL
921
pointer if no logging is to be performed. If the open function
922
returns C<0>, no I/O will be sent to the plugin.
924
The io_plugin struct has the following fields:
930
The C<type> field should always be set to SUDO_IO_PLUGIN
934
The C<version> field should be set to SUDO_API_VERSION.
936
This allows B<sudo> to determine the API version the plugin was
941
int (*open)(unsigned int version, sudo_conv_t conversation
942
sudo_printf_t plugin_printf, char * const settings[],
943
char * const user_info[], int argc, char * const argv[],
944
char * const user_env[], char * const plugin_options[]);
946
The I<open> function is run before the I<log_input>, I<log_output>
947
or I<show_version> functions are called. It is only called if the
948
version is being requested or the I<check_policy> function has
949
returned successfully. It returns 1 on success, 0 on failure, -1
950
if a general error occurred, or -2 if there was a usage error. In
951
the latter case, B<sudo> will print a usage message before it exits.
952
If an error occurs, the plugin may optionally call the conversation
953
or plugin_printf function with C<SUDO_CONF_ERROR_MSG> to present
954
additional error information to the user.
956
The function arguments are as follows:
962
The version passed in by B<sudo> allows the plugin to determine the
963
major and minor version number of the plugin API supported by
968
A pointer to the conversation function that may be used by the
969
I<show_version> function to display version information (see
970
show_version below). The conversation function may also be used
971
to display additional error message to the user.
972
The conversation function returns 0 on success and -1 on failure.
976
A pointer to a printf-style function that may be used by the
977
I<show_version> function to display version information (see
978
show_version below). The plugin_printf function may also be used
979
to display additional error message to the user.
980
The plugin_printf function returns number of characters printed on
981
success and -1 on failure.
985
A vector of user-supplied B<sudo> settings in the form of "name=value"
986
strings. The vector is terminated by a C<NULL> pointer. These
987
settings correspond to flags the user specified when running B<sudo>.
988
As such, they will only be present when the corresponding flag has
989
been specified on the command line.
991
When parsing I<settings>, the plugin should split on the B<first>
992
equal sign ('=') since the I<name> field will never include one
993
itself but the I<value> might.
995
See the L<Policy Plugin API> section for a list of all possible settings.
999
A vector of information about the user running the command in the form of
1000
"name=value" strings. The vector is terminated by a C<NULL> pointer.
1002
When parsing I<user_info>, the plugin should split on the B<first>
1003
equal sign ('=') since the I<name> field will never include one
1004
itself but the I<value> might.
1006
See the L<Policy Plugin API> section for a list of all possible strings.
1010
The number of elements in I<argv>, not counting the final C<NULL>
1015
If non-C<NULL>, an argument vector describing a command the user
1016
wishes to run in the same form as what would be passed to the
1017
execve() system call.
1021
The user's environment in the form of a C<NULL>-terminated vector of
1022
"name=value" strings.
1024
When parsing I<user_env>, the plugin should split on the B<first>
1025
equal sign ('=') since the I<name> field will never include one
1026
itself but the I<value> might.
1028
=item plugin_options
1030
Any (non-comment) strings immediately after the plugin path are
1031
treated as arguments to the plugin. These arguments are split on
1032
a white space boundary and are passed to the plugin in the form of
1033
a C<NULL>-terminated array of strings. If no arguments were
1034
specified, I<plugin_options> will be the NULL pointer.
1036
NOTE: the I<plugin_options> parameter is only available starting with
1037
API version 1.2. A plugin B<must> check the API version specified
1038
by the B<sudo> front end before using I<plugin_options>. Failure to
1039
do so may result in a crash.
1045
void (*close)(int exit_status, int error);
1047
The C<close> function is called when the command being run by B<sudo>
1050
The function arguments are as follows:
1056
The command's exit status, as returned by the wait(2) system call.
1057
The value of C<exit_status> is undefined if C<error> is non-zero.
1061
If the command could not be executed, this is set to the value of
1062
C<errno> set by the execve(2) system call. If the command was
1063
successfully executed, the value of C<error> is 0.
1069
int (*show_version)(int verbose);
1071
The C<show_version> function is called by B<sudo> when the user specifies
1072
the C<-V> option. The plugin may display its version information
1073
to the user via the conversation or plugin_printf function using
1074
C<SUDO_CONV_INFO_MSG>. If the user requests detailed version
1075
information, the verbose flag will be set.
1079
int (*log_ttyin)(const char *buf, unsigned int len);
1081
The I<log_ttyin> function is called whenever data can be read from
1082
the user but before it is passed to the running command. This
1083
allows the plugin to reject data if it chooses to (for instance
1084
if the input contains banned content). Returns C<1> if the data
1085
should be passed to the command, C<0> if the data is rejected
1086
(which will terminate the command) or C<-1> if an error occurred.
1088
The function arguments are as follows:
1094
The buffer containing user input.
1098
The length of I<buf> in bytes.
1104
int (*log_ttyout)(const char *buf, unsigned int len);
1106
The I<log_ttyout> function is called whenever data can be read from
1107
the command but before it is written to the user's terminal. This
1108
allows the plugin to reject data if it chooses to (for instance
1109
if the output contains banned content). Returns C<1> if the data
1110
should be passed to the user, C<0> if the data is rejected
1111
(which will terminate the command) or C<-1> if an error occurred.
1113
The function arguments are as follows:
1119
The buffer containing command output.
1123
The length of I<buf> in bytes.
1129
int (*log_stdin)(const char *buf, unsigned int len);
1131
The I<log_stdin> function is only used if the standard input does
1132
not correspond to a tty device. It is called whenever data can be
1133
read from the standard input but before it is passed to the running
1134
command. This allows the plugin to reject data if it chooses to
1135
(for instance if the input contains banned content). Returns C<1>
1136
if the data should be passed to the command, C<0> if the data is
1137
rejected (which will terminate the command) or C<-1> if an error
1140
The function arguments are as follows:
1146
The buffer containing user input.
1150
The length of I<buf> in bytes.
1156
int (*log_stdout)(const char *buf, unsigned int len);
1158
The I<log_stdout> function is only used if the standard output does
1159
not correspond to a tty device. It is called whenever data can be
1160
read from the command but before it is written to the standard
1161
output. This allows the plugin to reject data if it chooses to
1162
(for instance if the output contains banned content). Returns C<1>
1163
if the data should be passed to the user, C<0> if the data is
1164
rejected (which will terminate the command) or C<-1> if an error
1167
The function arguments are as follows:
1173
The buffer containing command output.
1177
The length of I<buf> in bytes.
1183
int (*log_stderr)(const char *buf, unsigned int len);
1185
The I<log_stderr> function is only used if the standard error does
1186
not correspond to a tty device. It is called whenever data can be
1187
read from the command but before it is written to the standard
1188
error. This allows the plugin to reject data if it chooses to
1189
(for instance if the output contains banned content). Returns C<1>
1190
if the data should be passed to the user, C<0> if the data is
1191
rejected (which will terminate the command) or C<-1> if an error
1194
The function arguments are as follows:
1200
The buffer containing command output.
1204
The length of I<buf> in bytes.
1208
=item register_hooks
1210
See the L<Policy Plugin API> section for a description of
1213
=item deregister_hooks
1215
See the L<Policy Plugin API> section for a description of
1216
C<deregister_hooks>.
1220
=head3 I/O Plugin Version Macros
1222
Same as for the L<Policy Plugin API>.
1224
=head2 Hook Function API
1226
Beginning with plugin API version 1.2, it is possible to install
1227
hooks for certain functions called by the B<sudo> front end.
1229
Currently, the only supported hooks relate to the handling of
1230
environment variables. Hooks can be used to intercept attempts to
1231
get, set, or remove environment variables so that these changes can
1232
be reflected in the version of the environment that is used to
1233
execute a command. A future version of the API will support
1234
hooking internal B<sudo> front end functions as well.
1236
=head3 Hook structure
1238
Hooks in B<sudo> are described by the following structure:
1240
typedef int (*sudo_hook_fn_t)();
1245
sudo_hook_fn_t hook_fn;
1249
The C<sudo_hook> structure has the following fields:
1255
The C<hook_version> field should be set to SUDO_HOOK_VERSION.
1259
The C<hook_type> field may be one of the following supported hook types:
1263
=item SUDO_HOOK_SETENV
1265
The C library C<setenv()> function. Any registered hooks will run
1266
before the C library implementation. The C<hook_fn> field should
1267
be a function that matches the following typedef:
1269
typedef int (*sudo_hook_fn_setenv_t)(const char *name,
1270
const char *value, int overwrite, void *closure);
1272
If the registered hook does not match the typedef the results are
1275
=item SUDO_HOOK_UNSETENV
1277
The C library C<unsetenv()> function. Any registered hooks will run
1278
before the C library implementation. The C<hook_fn> field should
1279
be a function that matches the following typedef:
1281
typedef int (*sudo_hook_fn_unsetenv_t)(const char *name,
1284
=item SUDO_HOOK_GETENV
1286
The C library C<getenv()> function. Any registered hooks will run
1287
before the C library implementation. The C<hook_fn> field should
1288
be a function that matches the following typedef:
1290
typedef int (*sudo_hook_fn_getenv_t)(const char *name,
1291
char **value, void *closure);
1293
If the registered hook does not match the typedef the results are
1296
=item SUDO_HOOK_PUTENV
1298
The C library C<putenv()> function. Any registered hooks will run
1299
before the C library implementation. The C<hook_fn> field should
1300
be a function that matches the following typedef:
1302
typedef int (*sudo_hook_fn_putenv_t)(char *string,
1305
If the registered hook does not match the typedef the results are
1312
sudo_hook_fn_t hook_fn;
1314
The C<hook_fn> field should be set to the plugin's hook implementation.
1315
The actual function arguments will vary depending on the C<hook_type>
1316
(see C<hook_type> above). In all cases, the C<closure> field of
1317
C<struct sudo_hook> is passed as the last function parameter. This
1318
can be used to pass arbitrary data to the plugin's hook implementation.
1320
The function return value may be one of the following:
1324
=item SUDO_HOOK_RET_ERROR
1326
The hook function encountered an error.
1328
=item SUDO_HOOK_RET_NEXT
1330
The hook completed without error, go on to the next hook (including
1331
the native implementation if applicable). For example, a C<getenv>
1332
hook might return C<SUDO_HOOK_RET_NEXT> if the specified variable
1333
was not found in the private copy of the environment.
1335
=item SUDO_HOOK_RET_STOP
1337
The hook completed without error, stop processing hooks for this
1338
invocation. This can be used to replace the native implementation.
1339
For example, a C<setenv> hook that operates on a private copy of
1340
the environment but leaves C<environ> unchanged.
1346
Note that it is very easy to create an infinite loop when hooking
1347
C library functions. For example, a C<getenv> hook that calls the
1348
C<snprintf> function may create a loop if the C<snprintf> implementation
1349
calls C<getenv> to check the locale. To prevent this, you may wish
1350
to use a static variable in the hook function to guard against
1353
static int in_progress = 0; /* avoid recursion */
1355
return SUDO_HOOK_RET_NEXT;
1359
return SUDO_HOOK_RET_STOP;
1361
=head3 Hook API Version Macros
1363
/* Hook API version major/minor */
1364
#define SUDO_HOOK_VERSION_MAJOR 1
1365
#define SUDO_HOOK_VERSION_MINOR 0
1366
#define SUDO_HOOK_MKVERSION(x, y) ((x << 16) | y)
1367
#define SUDO_HOOK_VERSION SUDO_HOOK_MKVERSION(SUDO_HOOK_VERSION_MAJOR,\
1368
SUDO_HOOK_VERSION_MINOR)
1370
/* Getters and setters for hook API version */
1371
#define SUDO_HOOK_VERSION_GET_MAJOR(v) ((v) >> 16)
1372
#define SUDO_HOOK_VERSION_GET_MINOR(v) ((v) & 0xffff)
1373
#define SUDO_HOOK_VERSION_SET_MAJOR(vp, n) do { \
1374
*(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
1376
#define SUDO_HOOK_VERSION_SET_MINOR(vp, n) do { \
1377
*(vp) = (*(vp) & 0xffff0000) | (n); \
1380
=head2 Conversation API
1382
If the plugin needs to interact with the user, it may do so via the
1383
conversation function. A plugin should not attempt to read directly
1384
from the standard input or the user's tty (neither of which are
1385
guaranteed to exist). The caller must include a trailing newline
1386
in C<msg> if one is to be printed.
1388
A printf-style function is also available that can be used to display
1389
informational or error messages to the user, which is usually more
1390
convenient for simple messages where no use input is required.
1392
struct sudo_conv_message {
1393
#define SUDO_CONV_PROMPT_ECHO_OFF 0x0001 /* do not echo user input */
1394
#define SUDO_CONV_PROMPT_ECHO_ON 0x0002 /* echo user input */
1395
#define SUDO_CONV_ERROR_MSG 0x0003 /* error message */
1396
#define SUDO_CONV_INFO_MSG 0x0004 /* informational message */
1397
#define SUDO_CONV_PROMPT_MASK 0x0005 /* mask user input */
1398
#define SUDO_CONV_DEBUG_MSG 0x0006 /* debugging message */
1399
#define SUDO_CONV_PROMPT_ECHO_OK 0x1000 /* flag: allow echo if no tty */
1405
struct sudo_conv_reply {
1409
typedef int (*sudo_conv_t)(int num_msgs,
1410
const struct sudo_conv_message msgs[],
1411
struct sudo_conv_reply replies[]);
1413
typedef int (*sudo_printf_t)(int msg_type, const char *fmt, ...);
1415
Pointers to the conversation and printf-style functions are passed
1416
in to the plugin's C<open> function when the plugin is initialized.
1418
To use the conversation function, the plugin must pass an array of
1419
C<sudo_conv_message> and C<sudo_conv_reply> structures. There must
1420
be a C<struct sudo_conv_message> and C<struct sudo_conv_reply> for
1421
each message in the conversation. The plugin is responsible for
1422
freeing the reply buffer filled in to the C<struct sudo_conv_reply>,
1425
The printf-style function uses the same underlying mechanism as the
1426
conversation function but only supports C<SUDO_CONV_INFO_MSG>,
1427
C<SUDO_CONV_ERROR_MSG> and C<SUDO_CONV_DEBUG_MSG> for the I<msg_type>
1428
parameter. It can be more convenient than using the conversation
1429
function if no user reply is needed and supports standard printf()
1432
Unlike, C<SUDO_CONV_INFO_MSG> and C<SUDO_CONV_ERROR_MSG>, messages
1433
sent with the <SUDO_CONV_DEBUG_MSG> I<msg_type> are not directly
1434
user-visible. Instead, they are logged to the file specified in
1435
the C<Debug> statement (if any) in the F<@sysconfdir@/sudo.conf>
1436
file. This allows a plugin to log debugging information and is
1437
intended to be used in conjunction with the I<debug_flags> setting.
1439
See the sample plugin for an example of the conversation function usage.
1441
=head2 Sudoers Group Plugin API
1443
The I<sudoers> module supports a plugin interface to allow non-Unix
1444
group lookups. This can be used to query a group source other than
1445
the standard Unix group database. A sample group plugin is bundled
1446
with B<sudo> that implements file-based lookups. Third party group
1447
plugins include a QAS AD plugin available from Quest Software.
1449
A group plugin must declare and populate a C<sudoers_group_plugin>
1450
struct in the global scope. This structure contains pointers to
1451
the functions that implement plugin initialization, cleanup and
1454
struct sudoers_group_plugin {
1455
unsigned int version;
1456
int (*init)(int version, sudo_printf_t sudo_printf,
1457
char *const argv[]);
1458
void (*cleanup)(void);
1459
int (*query)(const char *user, const char *group,
1460
const struct passwd *pwd);
1463
The C<sudoers_group_plugin> struct has the following fields:
1469
The C<version> field should be set to GROUP_API_VERSION.
1471
This allows I<sudoers> to determine the API version the group plugin
1476
int (*init)(int version, sudo_printf_t plugin_printf,
1477
char *const argv[]);
1479
The I<init> function is called after I<sudoers> has been parsed but
1480
before any policy checks. It returns 1 on success, 0 on failure
1481
(or if the plugin is not configured), and -1 if a error occurred.
1482
If an error occurs, the plugin may call the plugin_printf function
1483
with C<SUDO_CONF_ERROR_MSG> to present additional error information
1486
The function arguments are as follows:
1492
The version passed in by I<sudoers> allows the plugin to determine the
1493
major and minor version number of the group plugin API supported by
1498
A pointer to a printf-style function that may be used to display
1499
informational or error message to the user.
1500
Returns the number of characters printed on success and -1 on failure.
1504
A NULL-terminated array of arguments generated from the I<group_plugin>
1505
option in I<sudoers>. If no arguments were given, I<argv> will be
1514
The I<cleanup> function is called when I<sudoers> has finished its
1515
group checks. The plugin should free any memory it has allocated
1516
and close open file handles.
1520
int (*query)(const char *user, const char *group,
1521
const struct passwd *pwd);
1523
The I<query> function is used to ask the group plugin whether I<user>
1524
is a member of I<group>.
1526
The function arguments are as follows:
1532
The name of the user being looked up in the external group database.
1536
The name of the group being queried.
1540
The password database entry for I<user>, if any. If I<user> is not
1541
present in the password database, I<pwd> will be C<NULL>.
1547
=head3 Group API Version Macros
1549
/* Sudoers group plugin version major/minor */
1550
#define GROUP_API_VERSION_MAJOR 1
1551
#define GROUP_API_VERSION_MINOR 0
1552
#define GROUP_API_VERSION ((GROUP_API_VERSION_MAJOR << 16) | \
1553
GROUP_API_VERSION_MINOR)
1555
/* Getters and setters for group version */
1556
#define GROUP_API_VERSION_GET_MAJOR(v) ((v) >> 16)
1557
#define GROUP_API_VERSION_GET_MINOR(v) ((v) & 0xffff)
1558
#define GROUP_API_VERSION_SET_MAJOR(vp, n) do { \
1559
*(vp) = (*(vp) & 0x0000ffff) | ((n) << 16); \
1561
#define GROUP_API_VERSION_SET_MINOR(vp, n) do { \
1562
*(vp) = (*(vp) & 0xffff0000) | (n); \
1565
=head1 PLUGIN API CHANGELOG
1567
The following revisions have been made to the Sudo Plugin API.
1573
Initial API version.
1577
The I/O logging plugin's C<open> function was modified to take the
1578
C<command_info> list as an argument.
1582
The Policy and I/O logging plugins' C<open> functions are now passed
1583
a list of plugin options if any are specified in F<@sysconfdir@/sudo.conf>.
1585
A simple hooks API has been introduced to allow plugins to hook in to the
1586
system's environment handling functions.
1588
The C<init_session> Policy plugin function is now passed a pointer
1589
to the user environment which can be updated as needed. This can
1590
be used to merge in environment variables stored in the PAM handle
1591
before a command is run.
1598
L<sudoers(5)>, L<sudo(8)>
1602
If you feel you have found a bug in B<sudo>, please submit a bug report
1603
at http://www.sudo.ws/sudo/bugs/
1607
Limited free support is available via the sudo-workers mailing list,
1608
see http://www.sudo.ws/mailman/listinfo/sudo-workers to subscribe or
1609
search the archives.
1613
B<sudo> is provided ``AS IS'' and any express or implied warranties,
1614
including, but not limited to, the implied warranties of merchantability
1615
and fitness for a particular purpose are disclaimed. See the LICENSE
1616
file distributed with B<sudo> or http://www.sudo.ws/sudo/license.html
1617
for complete details.