Avoid a -Wshadow warning on Solaris 9.
This commit is contained in:
@@ -16,7 +16,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.TH "SUDO_PLUGIN" "5" "September 11, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
.TH "SUDO_PLUGIN" "5" "October 7, 2022" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
|
||||||
.nh
|
.nh
|
||||||
.if n .ad l
|
.if n .ad l
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
@@ -70,7 +70,7 @@ struct policy_plugin {
|
|||||||
unsigned int type; /* always SUDO_POLICY_PLUGIN */
|
unsigned int type; /* always SUDO_POLICY_PLUGIN */
|
||||||
unsigned int version; /* always SUDO_API_VERSION */
|
unsigned int version; /* always SUDO_API_VERSION */
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t plugin_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], char * const user_env[],
|
char * const user_info[], char * const user_env[],
|
||||||
char * const plugin_options[], const char **errstr);
|
char * const plugin_options[], const char **errstr);
|
||||||
void (*close)(int exit_status, int error);
|
void (*close)(int exit_status, int error);
|
||||||
@@ -79,9 +79,9 @@ struct policy_plugin {
|
|||||||
char *env_add[], char **command_info[],
|
char *env_add[], char **command_info[],
|
||||||
char **argv_out[], char **user_env_out[], const char **errstr);
|
char **argv_out[], char **user_env_out[], const char **errstr);
|
||||||
int (*list)(int argc, char * const argv[], int verbose,
|
int (*list)(int argc, char * const argv[], int verbose,
|
||||||
const char *list_user, const char **errstr);
|
const char *user, const char **errstr);
|
||||||
int (*validate)(const char **errstr);
|
int (*validate)(const char **errstr);
|
||||||
void (*invalidate)(int remove);
|
void (*invalidate)(int rmcred);
|
||||||
int (*init_session)(struct passwd *pwd, char **user_env[],
|
int (*init_session)(struct passwd *pwd, char **user_env[],
|
||||||
const char **errstr);
|
const char **errstr);
|
||||||
void (*register_hooks)(int version,
|
void (*register_hooks)(int version,
|
||||||
@@ -117,7 +117,7 @@ built against.
|
|||||||
.nf
|
.nf
|
||||||
.RS 6n
|
.RS 6n
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t plugin_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], char * const user_env[],
|
char * const user_info[], char * const user_env[],
|
||||||
char * const plugin_options[], const char **errstr);
|
char * const plugin_options[], const char **errstr);
|
||||||
.RE
|
.RE
|
||||||
@@ -132,7 +132,7 @@ will print a usage message before it exits.
|
|||||||
If an error occurs, the plugin may optionally call the
|
If an error occurs, the plugin may optionally call the
|
||||||
\fBconversation\fR()
|
\fBconversation\fR()
|
||||||
or
|
or
|
||||||
\fBplugin_printf\fR()
|
\fBsudo_plugin_printf\fR()
|
||||||
function with
|
function with
|
||||||
\fRSUDO_CONF_ERROR_MSG\fR
|
\fRSUDO_CONF_ERROR_MSG\fR
|
||||||
to present additional error information to the user.
|
to present additional error information to the user.
|
||||||
@@ -154,7 +154,7 @@ function that can be used by the plugin to interact with the user (see
|
|||||||
for details).
|
for details).
|
||||||
Returns 0 on success and \-1 on failure.
|
Returns 0 on success and \-1 on failure.
|
||||||
.TP 6n
|
.TP 6n
|
||||||
\fIplugin_printf\fR
|
\fIsudo_plugin_printf\fR
|
||||||
A pointer to a
|
A pointer to a
|
||||||
\fBprintf\fR()-style
|
\fBprintf\fR()-style
|
||||||
function that may be used to display informational or error messages (see
|
function that may be used to display informational or error messages (see
|
||||||
@@ -822,7 +822,7 @@ system call.
|
|||||||
The plugin is responsible for displaying error information via the
|
The plugin is responsible for displaying error information via the
|
||||||
\fBconversation\fR()
|
\fBconversation\fR()
|
||||||
or
|
or
|
||||||
\fBplugin_printf\fR()
|
\fBsudo_plugin_printf\fR()
|
||||||
function.
|
function.
|
||||||
If the command was successfully executed, the value of
|
If the command was successfully executed, the value of
|
||||||
\fIerror\fR
|
\fIerror\fR
|
||||||
@@ -861,7 +861,7 @@ option.
|
|||||||
The plugin may display its version information to the user via the
|
The plugin may display its version information to the user via the
|
||||||
\fBconversation\fR()
|
\fBconversation\fR()
|
||||||
or
|
or
|
||||||
\fBplugin_printf\fR()
|
\fBsudo_plugin_printf\fR()
|
||||||
function using
|
function using
|
||||||
\fRSUDO_CONV_INFO_MSG\fR.
|
\fRSUDO_CONV_INFO_MSG\fR.
|
||||||
If the user requests detailed version information, the
|
If the user requests detailed version information, the
|
||||||
@@ -948,7 +948,7 @@ exits.
|
|||||||
If an error occurs, the plugin may optionally call the
|
If an error occurs, the plugin may optionally call the
|
||||||
\fBconversation\fR()
|
\fBconversation\fR()
|
||||||
or
|
or
|
||||||
\fBplugin_printf\fR()
|
\fBsudo_plugin_printf\fR()
|
||||||
function with
|
function with
|
||||||
\fRSUDO_CONF_ERROR_MSG\fR
|
\fRSUDO_CONF_ERROR_MSG\fR
|
||||||
to present additional error information to the user.
|
to present additional error information to the user.
|
||||||
@@ -1634,7 +1634,7 @@ Failure to do so may result in a crash.
|
|||||||
.nf
|
.nf
|
||||||
.RS 6n
|
.RS 6n
|
||||||
int (*list)(int argc, char * const argv[], int verbose,
|
int (*list)(int argc, char * const argv[], int verbose,
|
||||||
const char *list_user, const char **errstr);
|
const char *user, const char **errstr);
|
||||||
.RE
|
.RE
|
||||||
.fi
|
.fi
|
||||||
.RS 6n
|
.RS 6n
|
||||||
@@ -1644,7 +1644,7 @@ Returns 1 on success, 0 on failure, and \-1 on error.
|
|||||||
On error, the plugin may optionally call the
|
On error, the plugin may optionally call the
|
||||||
\fBconversation\fR()
|
\fBconversation\fR()
|
||||||
or
|
or
|
||||||
\fBplugin_printf\fR()
|
\fBsudo_plugin_printf\fR()
|
||||||
function with
|
function with
|
||||||
\fRSUDO_CONF_ERROR_MSG\fR
|
\fRSUDO_CONF_ERROR_MSG\fR
|
||||||
to present additional error information to
|
to present additional error information to
|
||||||
@@ -1653,7 +1653,7 @@ the user.
|
|||||||
Privileges should be output via the
|
Privileges should be output via the
|
||||||
\fBconversation\fR()
|
\fBconversation\fR()
|
||||||
or
|
or
|
||||||
\fBplugin_printf\fR()
|
\fBsudo_plugin_printf\fR()
|
||||||
function using
|
function using
|
||||||
\fRSUDO_CONV_INFO_MSG\fR.
|
\fRSUDO_CONV_INFO_MSG\fR.
|
||||||
.sp
|
.sp
|
||||||
@@ -1680,7 +1680,7 @@ to the command should be displayed along with any command line arguments.
|
|||||||
\fIverbose\fR
|
\fIverbose\fR
|
||||||
Flag indicating whether to list in verbose mode or not.
|
Flag indicating whether to list in verbose mode or not.
|
||||||
.TP 6n
|
.TP 6n
|
||||||
\fIlist_user\fR
|
\fIuser\fR
|
||||||
The name of a different user to list privileges for if the policy
|
The name of a different user to list privileges for if the policy
|
||||||
allows it.
|
allows it.
|
||||||
If
|
If
|
||||||
@@ -1749,7 +1749,7 @@ Returns 1 on success, 0 on failure, and \-1 on error.
|
|||||||
On error, the plugin may optionally call the
|
On error, the plugin may optionally call the
|
||||||
\fBconversation\fR()
|
\fBconversation\fR()
|
||||||
or
|
or
|
||||||
\fBplugin_printf\fR()
|
\fBsudo_plugin_printf\fR()
|
||||||
function with
|
function with
|
||||||
\fRSUDO_CONF_ERROR_MSG\fR
|
\fRSUDO_CONF_ERROR_MSG\fR
|
||||||
to present additional
|
to present additional
|
||||||
@@ -1791,7 +1791,7 @@ Failure to do so may result in a crash.
|
|||||||
\fIinvalidate\fR
|
\fIinvalidate\fR
|
||||||
.nf
|
.nf
|
||||||
.RS 6n
|
.RS 6n
|
||||||
void (*invalidate)(int remove);
|
void (*invalidate)(int rmcred);
|
||||||
.RE
|
.RE
|
||||||
.fi
|
.fi
|
||||||
.RS 6n
|
.RS 6n
|
||||||
@@ -1811,7 +1811,7 @@ that
|
|||||||
cache authentication credentials, this function will invalidate the
|
cache authentication credentials, this function will invalidate the
|
||||||
credentials.
|
credentials.
|
||||||
If the
|
If the
|
||||||
\fIremove\fR
|
\fIrmcred\fR
|
||||||
flag is non-zero, the plugin may remove
|
flag is non-zero, the plugin may remove
|
||||||
the credentials instead of simply invalidating them.
|
the credentials instead of simply invalidating them.
|
||||||
.sp
|
.sp
|
||||||
@@ -1853,7 +1853,7 @@ Returns 1 on success, 0 on failure, and \-1 on error.
|
|||||||
On error, the plugin may optionally call the
|
On error, the plugin may optionally call the
|
||||||
\fBconversation\fR()
|
\fBconversation\fR()
|
||||||
or
|
or
|
||||||
\fBplugin_printf\fR()
|
\fBsudo_plugin_printf\fR()
|
||||||
function with
|
function with
|
||||||
\fRSUDO_CONF_ERROR_MSG\fR
|
\fRSUDO_CONF_ERROR_MSG\fR
|
||||||
to present additional
|
to present additional
|
||||||
@@ -2097,7 +2097,7 @@ struct io_plugin {
|
|||||||
unsigned int type; /* always SUDO_IO_PLUGIN */
|
unsigned int type; /* always SUDO_IO_PLUGIN */
|
||||||
unsigned int version; /* always SUDO_API_VERSION */
|
unsigned int version; /* always SUDO_API_VERSION */
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t plugin_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], char * const command_info[],
|
char * const user_info[], char * const command_info[],
|
||||||
int argc, char * const argv[], char * const user_env[],
|
int argc, char * const argv[], char * const user_env[],
|
||||||
char * const plugin_options[], const char **errstr);
|
char * const plugin_options[], const char **errstr);
|
||||||
@@ -2197,7 +2197,7 @@ built against.
|
|||||||
.nf
|
.nf
|
||||||
.RS 6n
|
.RS 6n
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t plugin_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], char * const command_info[],
|
char * const user_info[], char * const command_info[],
|
||||||
int argc, char * const argv[], char * const user_env[],
|
int argc, char * const argv[], char * const user_env[],
|
||||||
char * const plugin_options[]);
|
char * const plugin_options[]);
|
||||||
@@ -2230,7 +2230,7 @@ will print a usage message before it exits.
|
|||||||
If an error occurs, the plugin may optionally call the
|
If an error occurs, the plugin may optionally call the
|
||||||
\fBconversation\fR()
|
\fBconversation\fR()
|
||||||
or
|
or
|
||||||
\fBplugin_printf\fR()
|
\fBsudo_plugin_printf\fR()
|
||||||
function with
|
function with
|
||||||
\fRSUDO_CONF_ERROR_MSG\fR
|
\fRSUDO_CONF_ERROR_MSG\fR
|
||||||
to present additional error information to the user.
|
to present additional error information to the user.
|
||||||
@@ -2259,7 +2259,7 @@ The
|
|||||||
\fBconversation\fR()
|
\fBconversation\fR()
|
||||||
function returns 0 on success and \-1 on failure.
|
function returns 0 on success and \-1 on failure.
|
||||||
.TP 6n
|
.TP 6n
|
||||||
\fIplugin_printf\fR
|
\fIsudo_plugin_printf\fR
|
||||||
A pointer to a
|
A pointer to a
|
||||||
\fBprintf\fR()-style
|
\fBprintf\fR()-style
|
||||||
function that may be used by the
|
function that may be used by the
|
||||||
@@ -2267,10 +2267,10 @@ function that may be used by the
|
|||||||
function to display version information (see
|
function to display version information (see
|
||||||
show_version below).
|
show_version below).
|
||||||
The
|
The
|
||||||
\fBplugin_printf\fR()
|
\fBsudo_plugin_printf\fR()
|
||||||
function may also be used to display additional error message to the user.
|
function may also be used to display additional error message to the user.
|
||||||
The
|
The
|
||||||
\fBplugin_printf\fR()
|
\fBsudo_plugin_printf\fR()
|
||||||
function returns number of characters printed on success and \-1 on failure.
|
function returns number of characters printed on success and \-1 on failure.
|
||||||
.TP 6n
|
.TP 6n
|
||||||
\fIsettings\fR
|
\fIsettings\fR
|
||||||
@@ -2511,7 +2511,7 @@ option.
|
|||||||
The plugin may display its version information to the user via the
|
The plugin may display its version information to the user via the
|
||||||
\fBconversation\fR()
|
\fBconversation\fR()
|
||||||
or
|
or
|
||||||
\fBplugin_printf\fR()
|
\fBsudo_plugin_printf\fR()
|
||||||
function using
|
function using
|
||||||
\fRSUDO_CONV_INFO_MSG\fR.
|
\fRSUDO_CONV_INFO_MSG\fR.
|
||||||
If the user requests detailed version information, the
|
If the user requests detailed version information, the
|
||||||
@@ -3008,7 +3008,7 @@ struct audit_plugin {
|
|||||||
unsigned int type; /* always SUDO_AUDIT_PLUGIN */
|
unsigned int type; /* always SUDO_AUDIT_PLUGIN */
|
||||||
unsigned int version; /* always SUDO_API_VERSION */
|
unsigned int version; /* always SUDO_API_VERSION */
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t sudo_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], int submit_optind,
|
char * const user_info[], int submit_optind,
|
||||||
char * const submit_argv[], char * const submit_envp[],
|
char * const submit_argv[], char * const submit_envp[],
|
||||||
char * const plugin_options[], const char **errstr);
|
char * const plugin_options[], const char **errstr);
|
||||||
@@ -3065,7 +3065,7 @@ built against.
|
|||||||
.nf
|
.nf
|
||||||
.RS 6n
|
.RS 6n
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t sudo_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], int submit_optind,
|
char * const user_info[], int submit_optind,
|
||||||
char * const submit_argv[], char * const submit_envp[],
|
char * const submit_argv[], char * const submit_envp[],
|
||||||
char * const plugin_options[], const char **errstr);
|
char * const plugin_options[], const char **errstr);
|
||||||
@@ -3687,7 +3687,7 @@ struct approval_plugin {
|
|||||||
unsigned int type; /* always SUDO_APPROVAL_PLUGIN */
|
unsigned int type; /* always SUDO_APPROVAL_PLUGIN */
|
||||||
unsigned int version; /* always SUDO_API_VERSION */
|
unsigned int version; /* always SUDO_API_VERSION */
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t sudo_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], int submit_optind,
|
char * const user_info[], int submit_optind,
|
||||||
char * const submit_argv[], char * const submit_envp[],
|
char * const submit_argv[], char * const submit_envp[],
|
||||||
char * const plugin_options[], const char **errstr);
|
char * const plugin_options[], const char **errstr);
|
||||||
@@ -3737,7 +3737,7 @@ built against.
|
|||||||
.nf
|
.nf
|
||||||
.RS 6n
|
.RS 6n
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t sudo_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], int submit_optind,
|
char * const user_info[], int submit_optind,
|
||||||
char * const submit_argv[], char * const submit_envp[],
|
char * const submit_argv[], char * const submit_envp[],
|
||||||
char * const plugin_options[], const char **errstr);
|
char * const plugin_options[], const char **errstr);
|
||||||
@@ -5013,7 +5013,7 @@ initialization, cleanup, and group lookup.
|
|||||||
.RS 0n
|
.RS 0n
|
||||||
struct sudoers_group_plugin {
|
struct sudoers_group_plugin {
|
||||||
unsigned int version;
|
unsigned int version;
|
||||||
int (*init)(int version, sudo_printf_t sudo_printf,
|
int (*init)(int version, sudo_printf_t sudo_plugin_printf,
|
||||||
char *const argv[]);
|
char *const argv[]);
|
||||||
void (*cleanup)(void);
|
void (*cleanup)(void);
|
||||||
int (*query)(const char *user, const char *group,
|
int (*query)(const char *user, const char *group,
|
||||||
@@ -5039,7 +5039,7 @@ was built against.
|
|||||||
\fIinit\fR
|
\fIinit\fR
|
||||||
.nf
|
.nf
|
||||||
.RS 6n
|
.RS 6n
|
||||||
int (*init)(int version, sudo_printf_t plugin_printf,
|
int (*init)(int version, sudo_printf_t sudo_plugin_printf,
|
||||||
char *const argv[]);
|
char *const argv[]);
|
||||||
.RE
|
.RE
|
||||||
.fi
|
.fi
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd September 11, 2022
|
.Dd October 7, 2022
|
||||||
.Dt SUDO_PLUGIN @mansectform@
|
.Dt SUDO_PLUGIN @mansectform@
|
||||||
.Os Sudo @PACKAGE_VERSION@
|
.Os Sudo @PACKAGE_VERSION@
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@@ -67,7 +67,7 @@ struct policy_plugin {
|
|||||||
unsigned int type; /* always SUDO_POLICY_PLUGIN */
|
unsigned int type; /* always SUDO_POLICY_PLUGIN */
|
||||||
unsigned int version; /* always SUDO_API_VERSION */
|
unsigned int version; /* always SUDO_API_VERSION */
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t plugin_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], char * const user_env[],
|
char * const user_info[], char * const user_env[],
|
||||||
char * const plugin_options[], const char **errstr);
|
char * const plugin_options[], const char **errstr);
|
||||||
void (*close)(int exit_status, int error);
|
void (*close)(int exit_status, int error);
|
||||||
@@ -76,9 +76,9 @@ struct policy_plugin {
|
|||||||
char *env_add[], char **command_info[],
|
char *env_add[], char **command_info[],
|
||||||
char **argv_out[], char **user_env_out[], const char **errstr);
|
char **argv_out[], char **user_env_out[], const char **errstr);
|
||||||
int (*list)(int argc, char * const argv[], int verbose,
|
int (*list)(int argc, char * const argv[], int verbose,
|
||||||
const char *list_user, const char **errstr);
|
const char *user, const char **errstr);
|
||||||
int (*validate)(const char **errstr);
|
int (*validate)(const char **errstr);
|
||||||
void (*invalidate)(int remove);
|
void (*invalidate)(int rmcred);
|
||||||
int (*init_session)(struct passwd *pwd, char **user_env[],
|
int (*init_session)(struct passwd *pwd, char **user_env[],
|
||||||
const char **errstr);
|
const char **errstr);
|
||||||
void (*register_hooks)(int version,
|
void (*register_hooks)(int version,
|
||||||
@@ -110,7 +110,7 @@ built against.
|
|||||||
.It Fa open
|
.It Fa open
|
||||||
.Bd -literal -compact
|
.Bd -literal -compact
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t plugin_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], char * const user_env[],
|
char * const user_info[], char * const user_env[],
|
||||||
char * const plugin_options[], const char **errstr);
|
char * const plugin_options[], const char **errstr);
|
||||||
.Ed
|
.Ed
|
||||||
@@ -123,7 +123,7 @@ will print a usage message before it exits.
|
|||||||
If an error occurs, the plugin may optionally call the
|
If an error occurs, the plugin may optionally call the
|
||||||
.Fn conversation
|
.Fn conversation
|
||||||
or
|
or
|
||||||
.Fn plugin_printf
|
.Fn sudo_plugin_printf
|
||||||
function with
|
function with
|
||||||
.Dv SUDO_CONF_ERROR_MSG
|
.Dv SUDO_CONF_ERROR_MSG
|
||||||
to present additional error information to the user.
|
to present additional error information to the user.
|
||||||
@@ -143,7 +143,7 @@ function that can be used by the plugin to interact with the user (see
|
|||||||
.Sx Conversation API
|
.Sx Conversation API
|
||||||
for details).
|
for details).
|
||||||
Returns 0 on success and \-1 on failure.
|
Returns 0 on success and \-1 on failure.
|
||||||
.It Fa plugin_printf
|
.It Fa sudo_plugin_printf
|
||||||
A pointer to a
|
A pointer to a
|
||||||
.Fn printf Ns -style
|
.Fn printf Ns -style
|
||||||
function that may be used to display informational or error messages (see
|
function that may be used to display informational or error messages (see
|
||||||
@@ -729,7 +729,7 @@ system call.
|
|||||||
The plugin is responsible for displaying error information via the
|
The plugin is responsible for displaying error information via the
|
||||||
.Fn conversation
|
.Fn conversation
|
||||||
or
|
or
|
||||||
.Fn plugin_printf
|
.Fn sudo_plugin_printf
|
||||||
function.
|
function.
|
||||||
If the command was successfully executed, the value of
|
If the command was successfully executed, the value of
|
||||||
.Fa error
|
.Fa error
|
||||||
@@ -764,7 +764,7 @@ option.
|
|||||||
The plugin may display its version information to the user via the
|
The plugin may display its version information to the user via the
|
||||||
.Fn conversation
|
.Fn conversation
|
||||||
or
|
or
|
||||||
.Fn plugin_printf
|
.Fn sudo_plugin_printf
|
||||||
function using
|
function using
|
||||||
.Dv SUDO_CONV_INFO_MSG .
|
.Dv SUDO_CONV_INFO_MSG .
|
||||||
If the user requests detailed version information, the
|
If the user requests detailed version information, the
|
||||||
@@ -846,7 +846,7 @@ exits.
|
|||||||
If an error occurs, the plugin may optionally call the
|
If an error occurs, the plugin may optionally call the
|
||||||
.Fn conversation
|
.Fn conversation
|
||||||
or
|
or
|
||||||
.Fn plugin_printf
|
.Fn sudo_plugin_printf
|
||||||
function with
|
function with
|
||||||
.Dv SUDO_CONF_ERROR_MSG
|
.Dv SUDO_CONF_ERROR_MSG
|
||||||
to present additional error information to the user.
|
to present additional error information to the user.
|
||||||
@@ -1462,7 +1462,7 @@ Failure to do so may result in a crash.
|
|||||||
.It Fa list
|
.It Fa list
|
||||||
.Bd -literal -compact
|
.Bd -literal -compact
|
||||||
int (*list)(int argc, char * const argv[], int verbose,
|
int (*list)(int argc, char * const argv[], int verbose,
|
||||||
const char *list_user, const char **errstr);
|
const char *user, const char **errstr);
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
List available privileges for the invoking user.
|
List available privileges for the invoking user.
|
||||||
@@ -1470,7 +1470,7 @@ Returns 1 on success, 0 on failure, and \-1 on error.
|
|||||||
On error, the plugin may optionally call the
|
On error, the plugin may optionally call the
|
||||||
.Fn conversation
|
.Fn conversation
|
||||||
or
|
or
|
||||||
.Fn plugin_printf
|
.Fn sudo_plugin_printf
|
||||||
function with
|
function with
|
||||||
.Dv SUDO_CONF_ERROR_MSG
|
.Dv SUDO_CONF_ERROR_MSG
|
||||||
to present additional error information to
|
to present additional error information to
|
||||||
@@ -1479,7 +1479,7 @@ the user.
|
|||||||
Privileges should be output via the
|
Privileges should be output via the
|
||||||
.Fn conversation
|
.Fn conversation
|
||||||
or
|
or
|
||||||
.Fn plugin_printf
|
.Fn sudo_plugin_printf
|
||||||
function using
|
function using
|
||||||
.Dv SUDO_CONV_INFO_MSG .
|
.Dv SUDO_CONV_INFO_MSG .
|
||||||
.Pp
|
.Pp
|
||||||
@@ -1503,7 +1503,7 @@ If the command is permitted by the policy, the fully-qualified path
|
|||||||
to the command should be displayed along with any command line arguments.
|
to the command should be displayed along with any command line arguments.
|
||||||
.It Fa verbose
|
.It Fa verbose
|
||||||
Flag indicating whether to list in verbose mode or not.
|
Flag indicating whether to list in verbose mode or not.
|
||||||
.It Fa list_user
|
.It Fa user
|
||||||
The name of a different user to list privileges for if the policy
|
The name of a different user to list privileges for if the policy
|
||||||
allows it.
|
allows it.
|
||||||
If
|
If
|
||||||
@@ -1564,7 +1564,7 @@ Returns 1 on success, 0 on failure, and \-1 on error.
|
|||||||
On error, the plugin may optionally call the
|
On error, the plugin may optionally call the
|
||||||
.Fn conversation
|
.Fn conversation
|
||||||
or
|
or
|
||||||
.Fn plugin_printf
|
.Fn sudo_plugin_printf
|
||||||
function with
|
function with
|
||||||
.Dv SUDO_CONF_ERROR_MSG
|
.Dv SUDO_CONF_ERROR_MSG
|
||||||
to present additional
|
to present additional
|
||||||
@@ -1601,7 +1601,7 @@ Failure to do so may result in a crash.
|
|||||||
.El
|
.El
|
||||||
.It Fa invalidate
|
.It Fa invalidate
|
||||||
.Bd -literal -compact
|
.Bd -literal -compact
|
||||||
void (*invalidate)(int remove);
|
void (*invalidate)(int rmcred);
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
The
|
The
|
||||||
@@ -1619,7 +1619,7 @@ that
|
|||||||
cache authentication credentials, this function will invalidate the
|
cache authentication credentials, this function will invalidate the
|
||||||
credentials.
|
credentials.
|
||||||
If the
|
If the
|
||||||
.Fa remove
|
.Fa rmcred
|
||||||
flag is non-zero, the plugin may remove
|
flag is non-zero, the plugin may remove
|
||||||
the credentials instead of simply invalidating them.
|
the credentials instead of simply invalidating them.
|
||||||
.Pp
|
.Pp
|
||||||
@@ -1656,7 +1656,7 @@ Returns 1 on success, 0 on failure, and \-1 on error.
|
|||||||
On error, the plugin may optionally call the
|
On error, the plugin may optionally call the
|
||||||
.Fn conversation
|
.Fn conversation
|
||||||
or
|
or
|
||||||
.Fn plugin_printf
|
.Fn sudo_plugin_printf
|
||||||
function with
|
function with
|
||||||
.Dv SUDO_CONF_ERROR_MSG
|
.Dv SUDO_CONF_ERROR_MSG
|
||||||
to present additional
|
to present additional
|
||||||
@@ -1877,7 +1877,7 @@ struct io_plugin {
|
|||||||
unsigned int type; /* always SUDO_IO_PLUGIN */
|
unsigned int type; /* always SUDO_IO_PLUGIN */
|
||||||
unsigned int version; /* always SUDO_API_VERSION */
|
unsigned int version; /* always SUDO_API_VERSION */
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t plugin_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], char * const command_info[],
|
char * const user_info[], char * const command_info[],
|
||||||
int argc, char * const argv[], char * const user_env[],
|
int argc, char * const argv[], char * const user_env[],
|
||||||
char * const plugin_options[], const char **errstr);
|
char * const plugin_options[], const char **errstr);
|
||||||
@@ -1973,7 +1973,7 @@ built against.
|
|||||||
.It Fa open
|
.It Fa open
|
||||||
.Bd -literal -compact
|
.Bd -literal -compact
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t plugin_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], char * const command_info[],
|
char * const user_info[], char * const command_info[],
|
||||||
int argc, char * const argv[], char * const user_env[],
|
int argc, char * const argv[], char * const user_env[],
|
||||||
char * const plugin_options[]);
|
char * const plugin_options[]);
|
||||||
@@ -2004,7 +2004,7 @@ will print a usage message before it exits.
|
|||||||
If an error occurs, the plugin may optionally call the
|
If an error occurs, the plugin may optionally call the
|
||||||
.Fn conversation
|
.Fn conversation
|
||||||
or
|
or
|
||||||
.Fn plugin_printf
|
.Fn sudo_plugin_printf
|
||||||
function with
|
function with
|
||||||
.Dv SUDO_CONF_ERROR_MSG
|
.Dv SUDO_CONF_ERROR_MSG
|
||||||
to present additional error information to the user.
|
to present additional error information to the user.
|
||||||
@@ -2031,7 +2031,7 @@ function may also be used to display additional error message to the user.
|
|||||||
The
|
The
|
||||||
.Fn conversation
|
.Fn conversation
|
||||||
function returns 0 on success and \-1 on failure.
|
function returns 0 on success and \-1 on failure.
|
||||||
.It Fa plugin_printf
|
.It Fa sudo_plugin_printf
|
||||||
A pointer to a
|
A pointer to a
|
||||||
.Fn printf Ns -style
|
.Fn printf Ns -style
|
||||||
function that may be used by the
|
function that may be used by the
|
||||||
@@ -2039,10 +2039,10 @@ function that may be used by the
|
|||||||
function to display version information (see
|
function to display version information (see
|
||||||
show_version below).
|
show_version below).
|
||||||
The
|
The
|
||||||
.Fn plugin_printf
|
.Fn sudo_plugin_printf
|
||||||
function may also be used to display additional error message to the user.
|
function may also be used to display additional error message to the user.
|
||||||
The
|
The
|
||||||
.Fn plugin_printf
|
.Fn sudo_plugin_printf
|
||||||
function returns number of characters printed on success and \-1 on failure.
|
function returns number of characters printed on success and \-1 on failure.
|
||||||
.It Fa settings
|
.It Fa settings
|
||||||
A vector of user-supplied
|
A vector of user-supplied
|
||||||
@@ -2258,7 +2258,7 @@ option.
|
|||||||
The plugin may display its version information to the user via the
|
The plugin may display its version information to the user via the
|
||||||
.Fn conversation
|
.Fn conversation
|
||||||
or
|
or
|
||||||
.Fn plugin_printf
|
.Fn sudo_plugin_printf
|
||||||
function using
|
function using
|
||||||
.Dv SUDO_CONV_INFO_MSG .
|
.Dv SUDO_CONV_INFO_MSG .
|
||||||
If the user requests detailed version information, the
|
If the user requests detailed version information, the
|
||||||
@@ -2686,7 +2686,7 @@ struct audit_plugin {
|
|||||||
unsigned int type; /* always SUDO_AUDIT_PLUGIN */
|
unsigned int type; /* always SUDO_AUDIT_PLUGIN */
|
||||||
unsigned int version; /* always SUDO_API_VERSION */
|
unsigned int version; /* always SUDO_API_VERSION */
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t sudo_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], int submit_optind,
|
char * const user_info[], int submit_optind,
|
||||||
char * const submit_argv[], char * const submit_envp[],
|
char * const submit_argv[], char * const submit_envp[],
|
||||||
char * const plugin_options[], const char **errstr);
|
char * const plugin_options[], const char **errstr);
|
||||||
@@ -2739,7 +2739,7 @@ built against.
|
|||||||
.It Fa open
|
.It Fa open
|
||||||
.Bd -literal -compact
|
.Bd -literal -compact
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t sudo_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], int submit_optind,
|
char * const user_info[], int submit_optind,
|
||||||
char * const submit_argv[], char * const submit_envp[],
|
char * const submit_argv[], char * const submit_envp[],
|
||||||
char * const plugin_options[], const char **errstr);
|
char * const plugin_options[], const char **errstr);
|
||||||
@@ -3291,7 +3291,7 @@ struct approval_plugin {
|
|||||||
unsigned int type; /* always SUDO_APPROVAL_PLUGIN */
|
unsigned int type; /* always SUDO_APPROVAL_PLUGIN */
|
||||||
unsigned int version; /* always SUDO_API_VERSION */
|
unsigned int version; /* always SUDO_API_VERSION */
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t sudo_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], int submit_optind,
|
char * const user_info[], int submit_optind,
|
||||||
char * const submit_argv[], char * const submit_envp[],
|
char * const submit_argv[], char * const submit_envp[],
|
||||||
char * const plugin_options[], const char **errstr);
|
char * const plugin_options[], const char **errstr);
|
||||||
@@ -3337,7 +3337,7 @@ built against.
|
|||||||
.It Fa open
|
.It Fa open
|
||||||
.Bd -literal -compact
|
.Bd -literal -compact
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t sudo_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], int submit_optind,
|
char * const user_info[], int submit_optind,
|
||||||
char * const submit_argv[], char * const submit_envp[],
|
char * const submit_argv[], char * const submit_envp[],
|
||||||
char * const plugin_options[], const char **errstr);
|
char * const plugin_options[], const char **errstr);
|
||||||
@@ -4446,7 +4446,7 @@ initialization, cleanup, and group lookup.
|
|||||||
.Bd -literal
|
.Bd -literal
|
||||||
struct sudoers_group_plugin {
|
struct sudoers_group_plugin {
|
||||||
unsigned int version;
|
unsigned int version;
|
||||||
int (*init)(int version, sudo_printf_t sudo_printf,
|
int (*init)(int version, sudo_printf_t sudo_plugin_printf,
|
||||||
char *const argv[]);
|
char *const argv[]);
|
||||||
void (*cleanup)(void);
|
void (*cleanup)(void);
|
||||||
int (*query)(const char *user, const char *group,
|
int (*query)(const char *user, const char *group,
|
||||||
@@ -4469,7 +4469,7 @@ to determine the API version the group plugin
|
|||||||
was built against.
|
was built against.
|
||||||
.It Fa init
|
.It Fa init
|
||||||
.Bd -literal -compact
|
.Bd -literal -compact
|
||||||
int (*init)(int version, sudo_printf_t plugin_printf,
|
int (*init)(int version, sudo_printf_t sudo_plugin_printf,
|
||||||
char *const argv[]);
|
char *const argv[]);
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
|
@@ -132,7 +132,7 @@ bool eventlog_accept(const struct eventlog *evlog, int flags, eventlog_json_call
|
|||||||
bool eventlog_exit(const struct eventlog *evlog, int flags);
|
bool eventlog_exit(const struct eventlog *evlog, int flags);
|
||||||
bool eventlog_alert(const struct eventlog *evlog, int flags, struct timespec *alert_time, const char *reason, const char *errstr);
|
bool eventlog_alert(const struct eventlog *evlog, int flags, struct timespec *alert_time, const char *reason, const char *errstr);
|
||||||
bool eventlog_reject(const struct eventlog *evlog, int flags, const char *reason, eventlog_json_callback_t info_cb, void *info);
|
bool eventlog_reject(const struct eventlog *evlog, int flags, const char *reason, eventlog_json_callback_t info_cb, void *info);
|
||||||
bool eventlog_store_json(struct json_container *json, const struct eventlog *evlog);
|
bool eventlog_store_json(struct json_container *jsonc, const struct eventlog *evlog);
|
||||||
size_t eventlog_writeln(FILE *fp, char *line, size_t len, size_t maxlen);
|
size_t eventlog_writeln(FILE *fp, char *line, size_t len, size_t maxlen);
|
||||||
void eventlog_free(struct eventlog *evlog);
|
void eventlog_free(struct eventlog *evlog);
|
||||||
void eventlog_set_type(int type);
|
void eventlog_set_type(int type);
|
||||||
|
@@ -65,34 +65,34 @@ struct json_container {
|
|||||||
bool need_comma;
|
bool need_comma;
|
||||||
};
|
};
|
||||||
|
|
||||||
sudo_dso_public bool sudo_json_init_v1(struct json_container *json, int indent, bool minimal, bool memfatal);
|
sudo_dso_public bool sudo_json_init_v1(struct json_container *jsonc, int indent, bool minimal, bool memfatal);
|
||||||
#define sudo_json_init(_a, _b, _c, _d) sudo_json_init_v1((_a), (_b), (_c), (_d))
|
#define sudo_json_init(_a, _b, _c, _d) sudo_json_init_v1((_a), (_b), (_c), (_d))
|
||||||
|
|
||||||
sudo_dso_public void sudo_json_free_v1(struct json_container *json);
|
sudo_dso_public void sudo_json_free_v1(struct json_container *jsonc);
|
||||||
#define sudo_json_free(_a) sudo_json_free_v1((_a))
|
#define sudo_json_free(_a) sudo_json_free_v1((_a))
|
||||||
|
|
||||||
sudo_dso_public bool sudo_json_open_object_v1(struct json_container *json, const char *name);
|
sudo_dso_public bool sudo_json_open_object_v1(struct json_container *jsonc, const char *name);
|
||||||
#define sudo_json_open_object(_a, _b) sudo_json_open_object_v1((_a), (_b))
|
#define sudo_json_open_object(_a, _b) sudo_json_open_object_v1((_a), (_b))
|
||||||
|
|
||||||
sudo_dso_public bool sudo_json_close_object_v1(struct json_container *json);
|
sudo_dso_public bool sudo_json_close_object_v1(struct json_container *jsonc);
|
||||||
#define sudo_json_close_object(_a) sudo_json_close_object_v1((_a))
|
#define sudo_json_close_object(_a) sudo_json_close_object_v1((_a))
|
||||||
|
|
||||||
sudo_dso_public bool sudo_json_open_array_v1(struct json_container *json, const char *name);
|
sudo_dso_public bool sudo_json_open_array_v1(struct json_container *jsonc, const char *name);
|
||||||
#define sudo_json_open_array(_a, _b) sudo_json_open_array_v1((_a), (_b))
|
#define sudo_json_open_array(_a, _b) sudo_json_open_array_v1((_a), (_b))
|
||||||
|
|
||||||
sudo_dso_public bool sudo_json_close_array_v1(struct json_container *json);
|
sudo_dso_public bool sudo_json_close_array_v1(struct json_container *jsonc);
|
||||||
#define sudo_json_close_array(_a) sudo_json_close_array_v1((_a))
|
#define sudo_json_close_array(_a) sudo_json_close_array_v1((_a))
|
||||||
|
|
||||||
sudo_dso_public bool sudo_json_add_value_v1(struct json_container *json, const char *name, struct json_value *value);
|
sudo_dso_public bool sudo_json_add_value_v1(struct json_container *jsonc, const char *name, struct json_value *value);
|
||||||
#define sudo_json_add_value(_a, _b, _c) sudo_json_add_value_v1((_a), (_b), (_c))
|
#define sudo_json_add_value(_a, _b, _c) sudo_json_add_value_v1((_a), (_b), (_c))
|
||||||
|
|
||||||
sudo_dso_public bool sudo_json_add_value_as_object_v1(struct json_container *json, const char *name, struct json_value *value);
|
sudo_dso_public bool sudo_json_add_value_as_object_v1(struct json_container *jsonc, const char *name, struct json_value *value);
|
||||||
#define sudo_json_add_value_as_object(_a, _b, _c) sudo_json_add_value_as_object_v1((_a), (_b), (_c))
|
#define sudo_json_add_value_as_object(_a, _b, _c) sudo_json_add_value_as_object_v1((_a), (_b), (_c))
|
||||||
|
|
||||||
sudo_dso_public char *sudo_json_get_buf_v1(struct json_container *json);
|
sudo_dso_public char *sudo_json_get_buf_v1(struct json_container *jsonc);
|
||||||
#define sudo_json_get_buf(_a) sudo_json_get_buf_v1((_a))
|
#define sudo_json_get_buf(_a) sudo_json_get_buf_v1((_a))
|
||||||
|
|
||||||
sudo_dso_public unsigned int sudo_json_get_len_v1(struct json_container *json);
|
sudo_dso_public unsigned int sudo_json_get_len_v1(struct json_container *jsonc);
|
||||||
#define sudo_json_get_len(_a) sudo_json_get_len_v1((_a))
|
#define sudo_json_get_len(_a) sudo_json_get_len_v1((_a))
|
||||||
|
|
||||||
#endif /* SUDO_JSON_H */
|
#endif /* SUDO_JSON_H */
|
||||||
|
@@ -165,7 +165,7 @@ struct policy_plugin {
|
|||||||
unsigned int type; /* always SUDO_POLICY_PLUGIN */
|
unsigned int type; /* always SUDO_POLICY_PLUGIN */
|
||||||
unsigned int version; /* always SUDO_API_VERSION */
|
unsigned int version; /* always SUDO_API_VERSION */
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t sudo_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], char * const user_env[],
|
char * const user_info[], char * const user_env[],
|
||||||
char * const plugin_options[], const char **errstr);
|
char * const plugin_options[], const char **errstr);
|
||||||
void (*close)(int exit_status, int error); /* wait status or error */
|
void (*close)(int exit_status, int error); /* wait status or error */
|
||||||
@@ -174,9 +174,9 @@ struct policy_plugin {
|
|||||||
char *env_add[], char **command_info[],
|
char *env_add[], char **command_info[],
|
||||||
char **argv_out[], char **user_env_out[], const char **errstr);
|
char **argv_out[], char **user_env_out[], const char **errstr);
|
||||||
int (*list)(int argc, char * const argv[], int verbose,
|
int (*list)(int argc, char * const argv[], int verbose,
|
||||||
const char *list_user, const char **errstr);
|
const char *user, const char **errstr);
|
||||||
int (*validate)(const char **errstr);
|
int (*validate)(const char **errstr);
|
||||||
void (*invalidate)(int remove);
|
void (*invalidate)(int rmcred);
|
||||||
int (*init_session)(struct passwd *pwd, char **user_env_out[],
|
int (*init_session)(struct passwd *pwd, char **user_env_out[],
|
||||||
const char **errstr);
|
const char **errstr);
|
||||||
void (*register_hooks)(int version, int (*register_hook)(struct sudo_hook *hook));
|
void (*register_hooks)(int version, int (*register_hook)(struct sudo_hook *hook));
|
||||||
@@ -190,7 +190,7 @@ struct io_plugin {
|
|||||||
unsigned int type; /* always SUDO_IO_PLUGIN */
|
unsigned int type; /* always SUDO_IO_PLUGIN */
|
||||||
unsigned int version; /* always SUDO_API_VERSION */
|
unsigned int version; /* always SUDO_API_VERSION */
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t sudo_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], char * const command_info[],
|
char * const user_info[], char * const command_info[],
|
||||||
int argc, char * const argv[], char * const user_env[],
|
int argc, char * const argv[], char * const user_env[],
|
||||||
char * const plugin_options[], const char **errstr);
|
char * const plugin_options[], const char **errstr);
|
||||||
@@ -223,7 +223,7 @@ struct audit_plugin {
|
|||||||
unsigned int type; /* always SUDO_AUDIT_PLUGIN */
|
unsigned int type; /* always SUDO_AUDIT_PLUGIN */
|
||||||
unsigned int version; /* always SUDO_API_VERSION */
|
unsigned int version; /* always SUDO_API_VERSION */
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t sudo_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], int submit_optind,
|
char * const user_info[], int submit_optind,
|
||||||
char * const submit_argv[], char * const submit_envp[],
|
char * const submit_argv[], char * const submit_envp[],
|
||||||
char * const plugin_options[], const char **errstr);
|
char * const plugin_options[], const char **errstr);
|
||||||
@@ -249,7 +249,7 @@ struct approval_plugin {
|
|||||||
unsigned int type; /* always SUDO_APPROVAL_PLUGIN */
|
unsigned int type; /* always SUDO_APPROVAL_PLUGIN */
|
||||||
unsigned int version; /* always SUDO_API_VERSION */
|
unsigned int version; /* always SUDO_API_VERSION */
|
||||||
int (*open)(unsigned int version, sudo_conv_t conversation,
|
int (*open)(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t sudo_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], int submit_optind,
|
char * const user_info[], int submit_optind,
|
||||||
char * const submit_argv[], char * const submit_envp[],
|
char * const submit_argv[], char * const submit_envp[],
|
||||||
char * const plugin_options[], const char **errstr);
|
char * const plugin_options[], const char **errstr);
|
||||||
@@ -279,7 +279,8 @@ struct approval_plugin {
|
|||||||
*/
|
*/
|
||||||
struct sudoers_group_plugin {
|
struct sudoers_group_plugin {
|
||||||
unsigned int version;
|
unsigned int version;
|
||||||
int (*init)(int version, sudo_printf_t sudo_printf, char *const argv[]);
|
int (*init)(int version, sudo_printf_t sudo_plugin_printf,
|
||||||
|
char *const argv[]);
|
||||||
void (*cleanup)(void);
|
void (*cleanup)(void);
|
||||||
int (*query)(const char *user, const char *group, const struct passwd *pwd);
|
int (*query)(const char *user, const char *group, const struct passwd *pwd);
|
||||||
};
|
};
|
||||||
|
@@ -627,24 +627,24 @@ send_mail(const struct eventlog *evlog, const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
json_add_timestamp(struct json_container *json, const char *name,
|
json_add_timestamp(struct json_container *jsonc, const char *name,
|
||||||
const struct timespec *ts, bool format_timestamp)
|
const struct timespec *ts, bool format_timestamp)
|
||||||
{
|
{
|
||||||
struct json_value json_value;
|
struct json_value json_value;
|
||||||
int len;
|
int len;
|
||||||
debug_decl(json_add_timestamp, SUDO_DEBUG_PLUGIN);
|
debug_decl(json_add_timestamp, SUDO_DEBUG_PLUGIN);
|
||||||
|
|
||||||
if (!sudo_json_open_object(json, name))
|
if (!sudo_json_open_object(jsonc, name))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = ts->tv_sec;
|
json_value.u.number = ts->tv_sec;
|
||||||
if (!sudo_json_add_value(json, "seconds", &json_value))
|
if (!sudo_json_add_value(jsonc, "seconds", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = ts->tv_nsec;
|
json_value.u.number = ts->tv_nsec;
|
||||||
if (!sudo_json_add_value(json, "nanoseconds", &json_value))
|
if (!sudo_json_add_value(jsonc, "nanoseconds", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
if (format_timestamp) {
|
if (format_timestamp) {
|
||||||
@@ -660,7 +660,7 @@ json_add_timestamp(struct json_container *json, const char *name,
|
|||||||
if (len != 0 && timebuf[sizeof(timebuf) - 1] == '\0') {
|
if (len != 0 && timebuf[sizeof(timebuf) - 1] == '\0') {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = timebuf; // -V507
|
json_value.u.string = timebuf; // -V507
|
||||||
if (!sudo_json_add_value(json, "iso8601", &json_value))
|
if (!sudo_json_add_value(jsonc, "iso8601", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -671,13 +671,13 @@ json_add_timestamp(struct json_container *json, const char *name,
|
|||||||
if (len != 0 && timebuf[sizeof(timebuf) - 1] == '\0') {
|
if (len != 0 && timebuf[sizeof(timebuf) - 1] == '\0') {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = timebuf; // -V507
|
json_value.u.string = timebuf; // -V507
|
||||||
if (!sudo_json_add_value(json, "localtime", &json_value))
|
if (!sudo_json_add_value(jsonc, "localtime", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sudo_json_close_object(json))
|
if (!sudo_json_close_object(jsonc))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
@@ -693,7 +693,7 @@ oom:
|
|||||||
* be stored and formatted by the caller.
|
* be stored and formatted by the caller.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
eventlog_store_json(struct json_container *json, const struct eventlog *evlog)
|
eventlog_store_json(struct json_container *jsonc, const struct eventlog *evlog)
|
||||||
{
|
{
|
||||||
struct json_value json_value;
|
struct json_value json_value;
|
||||||
size_t i;
|
size_t i;
|
||||||
@@ -712,112 +712,112 @@ eventlog_store_json(struct json_container *json, const struct eventlog *evlog)
|
|||||||
|
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = evlog->submituser;
|
json_value.u.string = evlog->submituser;
|
||||||
if (!sudo_json_add_value(json, "submituser", &json_value))
|
if (!sudo_json_add_value(jsonc, "submituser", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
if (evlog->command != NULL) {
|
if (evlog->command != NULL) {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = evlog->command;
|
json_value.u.string = evlog->command;
|
||||||
if (!sudo_json_add_value(json, "command", &json_value))
|
if (!sudo_json_add_value(jsonc, "command", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evlog->runuser != NULL) {
|
if (evlog->runuser != NULL) {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = evlog->runuser;
|
json_value.u.string = evlog->runuser;
|
||||||
if (!sudo_json_add_value(json, "runuser", &json_value))
|
if (!sudo_json_add_value(jsonc, "runuser", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evlog->rungroup != NULL) {
|
if (evlog->rungroup != NULL) {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = evlog->rungroup;
|
json_value.u.string = evlog->rungroup;
|
||||||
if (!sudo_json_add_value(json, "rungroup", &json_value))
|
if (!sudo_json_add_value(jsonc, "rungroup", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evlog->runchroot != NULL) {
|
if (evlog->runchroot != NULL) {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = evlog->runchroot;
|
json_value.u.string = evlog->runchroot;
|
||||||
if (!sudo_json_add_value(json, "runchroot", &json_value))
|
if (!sudo_json_add_value(jsonc, "runchroot", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evlog->runcwd != NULL) {
|
if (evlog->runcwd != NULL) {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = evlog->runcwd;
|
json_value.u.string = evlog->runcwd;
|
||||||
if (!sudo_json_add_value(json, "runcwd", &json_value))
|
if (!sudo_json_add_value(jsonc, "runcwd", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evlog->ttyname != NULL) {
|
if (evlog->ttyname != NULL) {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = evlog->ttyname;
|
json_value.u.string = evlog->ttyname;
|
||||||
if (!sudo_json_add_value(json, "ttyname", &json_value))
|
if (!sudo_json_add_value(jsonc, "ttyname", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evlog->submithost != NULL) {
|
if (evlog->submithost != NULL) {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = evlog->submithost;
|
json_value.u.string = evlog->submithost;
|
||||||
if (!sudo_json_add_value(json, "submithost", &json_value))
|
if (!sudo_json_add_value(jsonc, "submithost", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evlog->cwd != NULL) {
|
if (evlog->cwd != NULL) {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = evlog->cwd;
|
json_value.u.string = evlog->cwd;
|
||||||
if (!sudo_json_add_value(json, "submitcwd", &json_value))
|
if (!sudo_json_add_value(jsonc, "submitcwd", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evlog->rungroup!= NULL && evlog->rungid != (gid_t)-1) {
|
if (evlog->rungroup!= NULL && evlog->rungid != (gid_t)-1) {
|
||||||
json_value.type = JSON_ID;
|
json_value.type = JSON_ID;
|
||||||
json_value.u.id = evlog->rungid;
|
json_value.u.id = evlog->rungid;
|
||||||
if (!sudo_json_add_value(json, "rungid", &json_value))
|
if (!sudo_json_add_value(jsonc, "rungid", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evlog->runuid != (uid_t)-1) {
|
if (evlog->runuid != (uid_t)-1) {
|
||||||
json_value.type = JSON_ID;
|
json_value.type = JSON_ID;
|
||||||
json_value.u.id = evlog->runuid;
|
json_value.u.id = evlog->runuid;
|
||||||
if (!sudo_json_add_value(json, "runuid", &json_value))
|
if (!sudo_json_add_value(jsonc, "runuid", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = evlog->columns;
|
json_value.u.number = evlog->columns;
|
||||||
if (!sudo_json_add_value(json, "columns", &json_value))
|
if (!sudo_json_add_value(jsonc, "columns", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = evlog->lines;
|
json_value.u.number = evlog->lines;
|
||||||
if (!sudo_json_add_value(json, "lines", &json_value))
|
if (!sudo_json_add_value(jsonc, "lines", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
if (evlog->argv != NULL) {
|
if (evlog->argv != NULL) {
|
||||||
if (!sudo_json_open_array(json, "runargv"))
|
if (!sudo_json_open_array(jsonc, "runargv"))
|
||||||
goto oom;
|
goto oom;
|
||||||
for (i = 0; (cp = evlog->argv[i]) != NULL; i++) {
|
for (i = 0; (cp = evlog->argv[i]) != NULL; i++) {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = cp;
|
json_value.u.string = cp;
|
||||||
if (!sudo_json_add_value(json, NULL, &json_value))
|
if (!sudo_json_add_value(jsonc, NULL, &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
if (!sudo_json_close_array(json))
|
if (!sudo_json_close_array(jsonc))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evlog->envp != NULL) {
|
if (evlog->envp != NULL) {
|
||||||
if (!sudo_json_open_array(json, "runenv"))
|
if (!sudo_json_open_array(jsonc, "runenv"))
|
||||||
goto oom;
|
goto oom;
|
||||||
for (i = 0; (cp = evlog->envp[i]) != NULL; i++) {
|
for (i = 0; (cp = evlog->envp[i]) != NULL; i++) {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = cp;
|
json_value.u.string = cp;
|
||||||
if (!sudo_json_add_value(json, NULL, &json_value))
|
if (!sudo_json_add_value(jsonc, NULL, &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
if (!sudo_json_close_array(json))
|
if (!sudo_json_close_array(jsonc))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -829,9 +829,9 @@ oom:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
default_json_cb(struct json_container *json, void *v)
|
default_json_cb(struct json_container *jsonc, void *v)
|
||||||
{
|
{
|
||||||
return eventlog_store_json(json, v);
|
return eventlog_store_json(jsonc, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
@@ -840,7 +840,7 @@ format_json(int event_type, struct eventlog_args *args,
|
|||||||
{
|
{
|
||||||
eventlog_json_callback_t info_cb = args->json_info_cb;
|
eventlog_json_callback_t info_cb = args->json_info_cb;
|
||||||
void *info = args->json_info;
|
void *info = args->json_info;
|
||||||
struct json_container json = { 0 };
|
struct json_container jsonc = { 0 };
|
||||||
struct json_value json_value;
|
struct json_value json_value;
|
||||||
const char *time_str, *type_str;
|
const char *time_str, *type_str;
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
@@ -880,15 +880,15 @@ format_json(int event_type, struct eventlog_args *args,
|
|||||||
debug_return_str(NULL);
|
debug_return_str(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sudo_json_init(&json, 4, compact, false))
|
if (!sudo_json_init(&jsonc, 4, compact, false))
|
||||||
goto bad;
|
goto bad;
|
||||||
if (!sudo_json_open_object(&json, type_str))
|
if (!sudo_json_open_object(&jsonc, type_str))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
if (evlog != NULL && evlog->uuid_str[0] != '\0') {
|
if (evlog != NULL && evlog->uuid_str[0] != '\0') {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = evlog->uuid_str;
|
json_value.u.string = evlog->uuid_str;
|
||||||
if (!sudo_json_add_value(&json, "uuid", &json_value))
|
if (!sudo_json_add_value(&jsonc, "uuid", &json_value))
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -907,7 +907,7 @@ format_json(int event_type, struct eventlog_args *args,
|
|||||||
}
|
}
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = ereason ? ereason : args->reason;
|
json_value.u.string = ereason ? ereason : args->reason;
|
||||||
if (!sudo_json_add_value(&json, "reason", &json_value)) {
|
if (!sudo_json_add_value(&jsonc, "reason", &json_value)) {
|
||||||
free(ereason);
|
free(ereason);
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@@ -915,7 +915,7 @@ format_json(int event_type, struct eventlog_args *args,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Log event time on server (set earlier) */
|
/* Log event time on server (set earlier) */
|
||||||
if (!json_add_timestamp(&json, "server_time", &now, true)) {
|
if (!json_add_timestamp(&jsonc, "server_time", &now, true)) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"unable format timestamp");
|
"unable format timestamp");
|
||||||
goto bad;
|
goto bad;
|
||||||
@@ -923,7 +923,7 @@ format_json(int event_type, struct eventlog_args *args,
|
|||||||
|
|
||||||
/* Log event time from client */
|
/* Log event time from client */
|
||||||
if (args->event_time != NULL) {
|
if (args->event_time != NULL) {
|
||||||
if (!json_add_timestamp(&json, time_str, args->event_time, true)) {
|
if (!json_add_timestamp(&jsonc, time_str, args->event_time, true)) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"unable format timestamp");
|
"unable format timestamp");
|
||||||
goto bad;
|
goto bad;
|
||||||
@@ -938,7 +938,7 @@ format_json(int event_type, struct eventlog_args *args,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sudo_timespecisset(&evlog->run_time)) {
|
if (sudo_timespecisset(&evlog->run_time)) {
|
||||||
if (!json_add_timestamp(&json, "run_time", &evlog->run_time, false)) {
|
if (!json_add_timestamp(&jsonc, "run_time", &evlog->run_time, false)) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"unable format timestamp");
|
"unable format timestamp");
|
||||||
goto bad;
|
goto bad;
|
||||||
@@ -947,17 +947,17 @@ format_json(int event_type, struct eventlog_args *args,
|
|||||||
if (evlog->signal_name != NULL) {
|
if (evlog->signal_name != NULL) {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = evlog->signal_name;
|
json_value.u.string = evlog->signal_name;
|
||||||
if (!sudo_json_add_value(&json, "signal", &json_value))
|
if (!sudo_json_add_value(&jsonc, "signal", &json_value))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
json_value.type = JSON_BOOL;
|
json_value.type = JSON_BOOL;
|
||||||
json_value.u.boolean = evlog->dumped_core;
|
json_value.u.boolean = evlog->dumped_core;
|
||||||
if (!sudo_json_add_value(&json, "dumped_core", &json_value))
|
if (!sudo_json_add_value(&jsonc, "dumped_core", &json_value))
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = evlog->exit_value;
|
json_value.u.number = evlog->exit_value;
|
||||||
if (!sudo_json_add_value(&json, "exit_value", &json_value))
|
if (!sudo_json_add_value(&jsonc, "exit_value", &json_value))
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -966,18 +966,18 @@ format_json(int event_type, struct eventlog_args *args,
|
|||||||
if (evlog->peeraddr != NULL) {
|
if (evlog->peeraddr != NULL) {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = evlog->peeraddr;
|
json_value.u.string = evlog->peeraddr;
|
||||||
if (!sudo_json_add_value(&json, "peeraddr", &json_value))
|
if (!sudo_json_add_value(&jsonc, "peeraddr", &json_value))
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evlog->iolog_path != NULL) {
|
if (evlog->iolog_path != NULL) {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = evlog->iolog_path;
|
json_value.u.string = evlog->iolog_path;
|
||||||
if (!sudo_json_add_value(&json, "iolog_path", &json_value))
|
if (!sudo_json_add_value(&jsonc, "iolog_path", &json_value))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
if (sudo_timespecisset(&evlog->iolog_offset)) {
|
if (sudo_timespecisset(&evlog->iolog_offset)) {
|
||||||
if (!json_add_timestamp(&json, "iolog_offset", &evlog->iolog_offset, false)) {
|
if (!json_add_timestamp(&jsonc, "iolog_offset", &evlog->iolog_offset, false)) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"unable format timestamp");
|
"unable format timestamp");
|
||||||
goto bad;
|
goto bad;
|
||||||
@@ -988,18 +988,18 @@ format_json(int event_type, struct eventlog_args *args,
|
|||||||
|
|
||||||
/* Write log info. */
|
/* Write log info. */
|
||||||
if (info != NULL) {
|
if (info != NULL) {
|
||||||
if (!info_cb(&json, info))
|
if (!info_cb(&jsonc, info))
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sudo_json_close_object(&json))
|
if (!sudo_json_close_object(&jsonc))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
/* Caller is responsible for freeing the buffer. */
|
/* Caller is responsible for freeing the buffer. */
|
||||||
debug_return_str(sudo_json_get_buf(&json));
|
debug_return_str(sudo_json_get_buf(&jsonc));
|
||||||
|
|
||||||
bad:
|
bad:
|
||||||
sudo_json_free(&json);
|
sudo_json_free(&jsonc);
|
||||||
debug_return_str(NULL);
|
debug_return_str(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -153,34 +153,34 @@ iolog_write_info_file_legacy(int dfd, struct eventlog *evlog)
|
|||||||
static bool
|
static bool
|
||||||
iolog_write_info_file_json(int dfd, struct eventlog *evlog)
|
iolog_write_info_file_json(int dfd, struct eventlog *evlog)
|
||||||
{
|
{
|
||||||
struct json_container json;
|
struct json_container jsonc;
|
||||||
struct json_value json_value;
|
struct json_value json_value;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
debug_decl(iolog_write_info_file_json, SUDO_DEBUG_UTIL);
|
debug_decl(iolog_write_info_file_json, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
if (!sudo_json_init(&json, 4, false, false))
|
if (!sudo_json_init(&jsonc, 4, false, false))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
|
|
||||||
/* Timestamp */
|
/* Timestamp */
|
||||||
if (!sudo_json_open_object(&json, "timestamp"))
|
if (!sudo_json_open_object(&jsonc, "timestamp"))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = evlog->submit_time.tv_sec;
|
json_value.u.number = evlog->submit_time.tv_sec;
|
||||||
if (!sudo_json_add_value(&json, "seconds", &json_value))
|
if (!sudo_json_add_value(&jsonc, "seconds", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = evlog->submit_time.tv_nsec;
|
json_value.u.number = evlog->submit_time.tv_nsec;
|
||||||
if (!sudo_json_add_value(&json, "nanoseconds", &json_value))
|
if (!sudo_json_add_value(&jsonc, "nanoseconds", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
if (!sudo_json_close_object(&json))
|
if (!sudo_json_close_object(&jsonc))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
if (!eventlog_store_json(&json, evlog))
|
if (!eventlog_store_json(&jsonc, evlog))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
fd = iolog_openat(dfd, "log.json", O_CREAT|O_TRUNC|O_WRONLY);
|
fd = iolog_openat(dfd, "log.json", O_CREAT|O_TRUNC|O_WRONLY);
|
||||||
@@ -197,7 +197,7 @@ iolog_write_info_file_json(int dfd, struct eventlog *evlog)
|
|||||||
}
|
}
|
||||||
fd = -1;
|
fd = -1;
|
||||||
|
|
||||||
fprintf(fp, "{%s\n}\n", sudo_json_get_buf(&json));
|
fprintf(fp, "{%s\n}\n", sudo_json_get_buf(&jsonc));
|
||||||
fflush(fp);
|
fflush(fp);
|
||||||
if (ferror(fp)) {
|
if (ferror(fp)) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
|
||||||
@@ -211,7 +211,7 @@ iolog_write_info_file_json(int dfd, struct eventlog *evlog)
|
|||||||
oom:
|
oom:
|
||||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||||
done:
|
done:
|
||||||
sudo_json_free(&json);
|
sudo_json_free(&jsonc);
|
||||||
if (fp != NULL)
|
if (fp != NULL)
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
|
@@ -35,7 +35,7 @@
|
|||||||
sudo_dso_public int main(int argc, char *argv[]);
|
sudo_dso_public int main(int argc, char *argv[]);
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
json_print_object(struct json_container *json, struct json_object *object)
|
json_print_object(struct json_container *jsonc, struct json_object *object)
|
||||||
{
|
{
|
||||||
struct json_item *item;
|
struct json_item *item;
|
||||||
struct json_value json_value;
|
struct json_value json_value;
|
||||||
@@ -46,40 +46,40 @@ json_print_object(struct json_container *json, struct json_object *object)
|
|||||||
case JSON_STRING:
|
case JSON_STRING:
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = item->u.string;
|
json_value.u.string = item->u.string;
|
||||||
if (!sudo_json_add_value(json, item->name, &json_value))
|
if (!sudo_json_add_value(jsonc, item->name, &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
break;
|
break;
|
||||||
case JSON_NUMBER:
|
case JSON_NUMBER:
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = item->u.number;
|
json_value.u.number = item->u.number;
|
||||||
if (!sudo_json_add_value(json, item->name, &json_value))
|
if (!sudo_json_add_value(jsonc, item->name, &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
break;
|
break;
|
||||||
case JSON_OBJECT:
|
case JSON_OBJECT:
|
||||||
if (!sudo_json_open_object(json, item->name))
|
if (!sudo_json_open_object(jsonc, item->name))
|
||||||
goto oom;
|
goto oom;
|
||||||
if (!json_print_object(json, &item->u.child))
|
if (!json_print_object(jsonc, &item->u.child))
|
||||||
goto done;
|
goto done;
|
||||||
if (!sudo_json_close_object(json))
|
if (!sudo_json_close_object(jsonc))
|
||||||
goto oom;
|
goto oom;
|
||||||
break;
|
break;
|
||||||
case JSON_ARRAY:
|
case JSON_ARRAY:
|
||||||
if (!sudo_json_open_array(json, item->name))
|
if (!sudo_json_open_array(jsonc, item->name))
|
||||||
goto oom;
|
goto oom;
|
||||||
if (!json_print_object(json, &item->u.child))
|
if (!json_print_object(jsonc, &item->u.child))
|
||||||
goto done;
|
goto done;
|
||||||
if (!sudo_json_close_array(json))
|
if (!sudo_json_close_array(jsonc))
|
||||||
goto oom;
|
goto oom;
|
||||||
break;
|
break;
|
||||||
case JSON_BOOL:
|
case JSON_BOOL:
|
||||||
json_value.type = JSON_BOOL;
|
json_value.type = JSON_BOOL;
|
||||||
json_value.u.boolean = item->u.boolean;
|
json_value.u.boolean = item->u.boolean;
|
||||||
if (!sudo_json_add_value(json, item->name, &json_value))
|
if (!sudo_json_add_value(jsonc, item->name, &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
break;
|
break;
|
||||||
case JSON_NULL:
|
case JSON_NULL:
|
||||||
json_value.type = JSON_NULL;
|
json_value.type = JSON_NULL;
|
||||||
if (!sudo_json_add_value(json, item->name, &json_value))
|
if (!sudo_json_add_value(jsonc, item->name, &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -98,7 +98,7 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
json_format(struct json_container *json, struct json_object *object)
|
json_format(struct json_container *jsonc, struct json_object *object)
|
||||||
{
|
{
|
||||||
struct json_item *item;
|
struct json_item *item;
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
@@ -111,7 +111,7 @@ json_format(struct json_container *json, struct json_object *object)
|
|||||||
}
|
}
|
||||||
object = &item->u.child;
|
object = &item->u.child;
|
||||||
|
|
||||||
if (!json_print_object(json, object))
|
if (!json_print_object(jsonc, object))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
ret = true;
|
ret = true;
|
||||||
@@ -129,7 +129,7 @@ usage(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
compare(FILE *fp, const char *infile, struct json_container *json)
|
compare(FILE *fp, const char *infile, struct json_container *jsonc)
|
||||||
{
|
{
|
||||||
const char *cp;
|
const char *cp;
|
||||||
unsigned int lineno = 0;
|
unsigned int lineno = 0;
|
||||||
@@ -137,7 +137,7 @@ compare(FILE *fp, const char *infile, struct json_container *json)
|
|||||||
char *line = NULL;
|
char *line = NULL;
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
|
||||||
cp = sudo_json_get_buf(json);
|
cp = sudo_json_get_buf(jsonc);
|
||||||
|
|
||||||
while ((len = getdelim(&line, &linesize, '\n', fp)) != -1) {
|
while ((len = getdelim(&line, &linesize, '\n', fp)) != -1) {
|
||||||
lineno++;
|
lineno++;
|
||||||
@@ -192,7 +192,7 @@ main(int argc, char *argv[])
|
|||||||
usage();
|
usage();
|
||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
for (i = 0; i < argc; i++) {
|
||||||
struct json_container json;
|
struct json_container jsonc;
|
||||||
const char *infile = argv[i];
|
const char *infile = argv[i];
|
||||||
const char *outfile = argv[i];
|
const char *outfile = argv[i];
|
||||||
const char *cp;
|
const char *cp;
|
||||||
@@ -202,7 +202,7 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
ntests++;
|
ntests++;
|
||||||
|
|
||||||
if (!sudo_json_init(&json, 4, false, true)) {
|
if (!sudo_json_init(&jsonc, 4, false, true)) {
|
||||||
errors++;
|
errors++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -219,7 +219,7 @@ main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Format as pretty-printed JSON */
|
/* Format as pretty-printed JSON */
|
||||||
if (!json_format(&json, &root)) {
|
if (!json_format(&jsonc, &root)) {
|
||||||
errors++;
|
errors++;
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
@@ -237,18 +237,18 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
/* Compare output to expected output. */
|
/* Compare output to expected output. */
|
||||||
rewind(outfp);
|
rewind(outfp);
|
||||||
if (!compare(outfp, outfile, &json))
|
if (!compare(outfp, outfile, &jsonc))
|
||||||
errors++;
|
errors++;
|
||||||
|
|
||||||
/* Write the formatted output to stdout for -c (cat) */
|
/* Write the formatted output to stdout for -c (cat) */
|
||||||
if (cat) {
|
if (cat) {
|
||||||
fprintf(stdout, "{%s\n}\n", sudo_json_get_buf(&json));
|
fprintf(stdout, "{%s\n}\n", sudo_json_get_buf(&jsonc));
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
next:
|
next:
|
||||||
free_json_items(&root.items);
|
free_json_items(&root.items);
|
||||||
sudo_json_free(&json);
|
sudo_json_free(&jsonc);
|
||||||
if (infp != NULL)
|
if (infp != NULL)
|
||||||
fclose(infp);
|
fclose(infp);
|
||||||
if (outfp != NULL && outfp != infp)
|
if (outfp != NULL && outfp != infp)
|
||||||
|
174
lib/util/json.c
174
lib/util/json.c
@@ -44,13 +44,13 @@
|
|||||||
* Returns true on success, false if out of memory.
|
* Returns true on success, false if out of memory.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
json_expand_buf(struct json_container *json)
|
json_expand_buf(struct json_container *jsonc)
|
||||||
{
|
{
|
||||||
char *newbuf;
|
char *newbuf;
|
||||||
debug_decl(json_expand_buf, SUDO_DEBUG_UTIL);
|
debug_decl(json_expand_buf, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
if ((newbuf = reallocarray(json->buf, 2, json->bufsize)) == NULL) {
|
if ((newbuf = reallocarray(jsonc->buf, 2, jsonc->bufsize)) == NULL) {
|
||||||
if (json->memfatal) {
|
if (jsonc->memfatal) {
|
||||||
sudo_fatalx(U_("%s: %s"),
|
sudo_fatalx(U_("%s: %s"),
|
||||||
__func__, U_("unable to allocate memory"));
|
__func__, U_("unable to allocate memory"));
|
||||||
}
|
}
|
||||||
@@ -58,8 +58,8 @@ json_expand_buf(struct json_container *json)
|
|||||||
"%s: %s", __func__, "unable to allocate memory");
|
"%s: %s", __func__, "unable to allocate memory");
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
json->buf = newbuf;
|
jsonc->buf = newbuf;
|
||||||
json->bufsize *= 2;
|
jsonc->bufsize *= 2;
|
||||||
|
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
@@ -69,24 +69,24 @@ json_expand_buf(struct json_container *json)
|
|||||||
* Append "indent" number of blank characters.
|
* Append "indent" number of blank characters.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
json_new_line(struct json_container *json)
|
json_new_line(struct json_container *jsonc)
|
||||||
{
|
{
|
||||||
int indent = json->indent_level;
|
int indent = jsonc->indent_level;
|
||||||
debug_decl(json_new_line, SUDO_DEBUG_UTIL);
|
debug_decl(json_new_line, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
/* No non-essential white space in minimal mode. */
|
/* No non-essential white space in minimal mode. */
|
||||||
if (json->minimal)
|
if (jsonc->minimal)
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
|
|
||||||
while (json->buflen + 1 + indent >= json->bufsize) {
|
while (jsonc->buflen + 1 + indent >= jsonc->bufsize) {
|
||||||
if (!json_expand_buf(json))
|
if (!json_expand_buf(jsonc))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
json->buf[json->buflen++] = '\n';
|
jsonc->buf[jsonc->buflen++] = '\n';
|
||||||
while (indent--) {
|
while (indent--) {
|
||||||
json->buf[json->buflen++] = ' ';
|
jsonc->buf[jsonc->buflen++] = ' ';
|
||||||
}
|
}
|
||||||
json->buf[json->buflen] = '\0';
|
jsonc->buf[jsonc->buflen] = '\0';
|
||||||
|
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
@@ -96,20 +96,20 @@ json_new_line(struct json_container *json)
|
|||||||
* Does not perform any quoting.
|
* Does not perform any quoting.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
json_append_buf(struct json_container *json, const char *str)
|
json_append_buf(struct json_container *jsonc, const char *str)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
debug_decl(json_append_buf, SUDO_DEBUG_UTIL);
|
debug_decl(json_append_buf, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
len = strlen(str);
|
len = strlen(str);
|
||||||
while (json->buflen + len >= json->bufsize) {
|
while (jsonc->buflen + len >= jsonc->bufsize) {
|
||||||
if (!json_expand_buf(json))
|
if (!json_expand_buf(jsonc))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(json->buf + json->buflen, str, len);
|
memcpy(jsonc->buf + jsonc->buflen, str, len);
|
||||||
json->buflen += len;
|
jsonc->buflen += len;
|
||||||
json->buf[json->buflen] = '\0';
|
jsonc->buf[jsonc->buflen] = '\0';
|
||||||
|
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
@@ -119,12 +119,12 @@ json_append_buf(struct json_container *json, const char *str)
|
|||||||
* Does not support unicode escapes.
|
* Does not support unicode escapes.
|
||||||
*/
|
*/
|
||||||
static bool
|
static bool
|
||||||
json_append_string(struct json_container *json, const char *str)
|
json_append_string(struct json_container *jsonc, const char *str)
|
||||||
{
|
{
|
||||||
char ch;
|
char ch;
|
||||||
debug_decl(json_append_string, SUDO_DEBUG_UTIL);
|
debug_decl(json_append_string, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
if (!json_append_buf(json, "\""))
|
if (!json_append_buf(jsonc, "\""))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
while ((ch = *str++) != '\0') {
|
while ((ch = *str++) != '\0') {
|
||||||
char buf[3], *cp = buf;
|
char buf[3], *cp = buf;
|
||||||
@@ -157,29 +157,29 @@ json_append_string(struct json_container *json, const char *str)
|
|||||||
}
|
}
|
||||||
*cp++ = ch;
|
*cp++ = ch;
|
||||||
*cp++ = '\0';
|
*cp++ = '\0';
|
||||||
if (!json_append_buf(json, buf))
|
if (!json_append_buf(jsonc, buf))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
if (!json_append_buf(json, "\""))
|
if (!json_append_buf(jsonc, "\""))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
|
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sudo_json_init_v1(struct json_container *json, int indent, bool minimal,
|
sudo_json_init_v1(struct json_container *jsonc, int indent, bool minimal,
|
||||||
bool memfatal)
|
bool memfatal)
|
||||||
{
|
{
|
||||||
debug_decl(sudo_json_init, SUDO_DEBUG_UTIL);
|
debug_decl(sudo_json_init, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
memset(json, 0, sizeof(*json));
|
memset(jsonc, 0, sizeof(*jsonc));
|
||||||
json->indent_level = indent;
|
jsonc->indent_level = indent;
|
||||||
json->indent_increment = indent;
|
jsonc->indent_increment = indent;
|
||||||
json->minimal = minimal;
|
jsonc->minimal = minimal;
|
||||||
json->memfatal = memfatal;
|
jsonc->memfatal = memfatal;
|
||||||
json->buf = malloc(64 * 1024);
|
jsonc->buf = malloc(64 * 1024);
|
||||||
if (json->buf == NULL) {
|
if (jsonc->buf == NULL) {
|
||||||
if (json->memfatal) {
|
if (jsonc->memfatal) {
|
||||||
sudo_fatalx(U_("%s: %s"),
|
sudo_fatalx(U_("%s: %s"),
|
||||||
__func__, U_("unable to allocate memory"));
|
__func__, U_("unable to allocate memory"));
|
||||||
}
|
}
|
||||||
@@ -187,162 +187,162 @@ sudo_json_init_v1(struct json_container *json, int indent, bool minimal,
|
|||||||
"%s: %s", __func__, "unable to allocate memory");
|
"%s: %s", __func__, "unable to allocate memory");
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
*json->buf = '\0';
|
*jsonc->buf = '\0';
|
||||||
json->bufsize = 64 * 1024;
|
jsonc->bufsize = 64 * 1024;
|
||||||
|
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sudo_json_free_v1(struct json_container *json)
|
sudo_json_free_v1(struct json_container *jsonc)
|
||||||
{
|
{
|
||||||
debug_decl(sudo_json_free, SUDO_DEBUG_UTIL);
|
debug_decl(sudo_json_free, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
free(json->buf);
|
free(jsonc->buf);
|
||||||
memset(json, 0, sizeof(*json));
|
memset(jsonc, 0, sizeof(*jsonc));
|
||||||
|
|
||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sudo_json_open_object_v1(struct json_container *json, const char *name)
|
sudo_json_open_object_v1(struct json_container *jsonc, const char *name)
|
||||||
{
|
{
|
||||||
debug_decl(sudo_json_open_object, SUDO_DEBUG_UTIL);
|
debug_decl(sudo_json_open_object, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
/* Add comma if we are continuing an object/array. */
|
/* Add comma if we are continuing an object/array. */
|
||||||
if (json->need_comma) {
|
if (jsonc->need_comma) {
|
||||||
if (!json_append_buf(json, ","))
|
if (!json_append_buf(jsonc, ","))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
if (!json_new_line(json))
|
if (!json_new_line(jsonc))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
|
|
||||||
if (name != NULL) {
|
if (name != NULL) {
|
||||||
json_append_string(json, name);
|
json_append_string(jsonc, name);
|
||||||
if (!json_append_buf(json, json->minimal ? ":{" : ": {"))
|
if (!json_append_buf(jsonc, jsonc->minimal ? ":{" : ": {"))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
} else {
|
} else {
|
||||||
if (!json_append_buf(json, "{"))
|
if (!json_append_buf(jsonc, "{"))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
json->indent_level += json->indent_increment;
|
jsonc->indent_level += jsonc->indent_increment;
|
||||||
json->need_comma = false;
|
jsonc->need_comma = false;
|
||||||
|
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sudo_json_close_object_v1(struct json_container *json)
|
sudo_json_close_object_v1(struct json_container *jsonc)
|
||||||
{
|
{
|
||||||
debug_decl(sudo_json_close_object, SUDO_DEBUG_UTIL);
|
debug_decl(sudo_json_close_object, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
if (!json->minimal) {
|
if (!jsonc->minimal) {
|
||||||
json->indent_level -= json->indent_increment;
|
jsonc->indent_level -= jsonc->indent_increment;
|
||||||
if (!json_new_line(json))
|
if (!json_new_line(jsonc))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
if (!json_append_buf(json, "}"))
|
if (!json_append_buf(jsonc, "}"))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
|
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sudo_json_open_array_v1(struct json_container *json, const char *name)
|
sudo_json_open_array_v1(struct json_container *jsonc, const char *name)
|
||||||
{
|
{
|
||||||
debug_decl(sudo_json_open_array, SUDO_DEBUG_UTIL);
|
debug_decl(sudo_json_open_array, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
/* Add comma if we are continuing an object/array. */
|
/* Add comma if we are continuing an object/array. */
|
||||||
if (json->need_comma) {
|
if (jsonc->need_comma) {
|
||||||
if (!json_append_buf(json, ","))
|
if (!json_append_buf(jsonc, ","))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
if (!json_new_line(json))
|
if (!json_new_line(jsonc))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
|
|
||||||
if (name != NULL) {
|
if (name != NULL) {
|
||||||
json_append_string(json, name);
|
json_append_string(jsonc, name);
|
||||||
if (!json_append_buf(json, json->minimal ? ":[" : ": ["))
|
if (!json_append_buf(jsonc, jsonc->minimal ? ":[" : ": ["))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
} else {
|
} else {
|
||||||
if (!json_append_buf(json, "["))
|
if (!json_append_buf(jsonc, "["))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
json->indent_level += json->indent_increment;
|
jsonc->indent_level += jsonc->indent_increment;
|
||||||
json->need_comma = false;
|
jsonc->need_comma = false;
|
||||||
|
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sudo_json_close_array_v1(struct json_container *json)
|
sudo_json_close_array_v1(struct json_container *jsonc)
|
||||||
{
|
{
|
||||||
debug_decl(sudo_json_close_array, SUDO_DEBUG_UTIL);
|
debug_decl(sudo_json_close_array, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
if (!json->minimal) {
|
if (!jsonc->minimal) {
|
||||||
json->indent_level -= json->indent_increment;
|
jsonc->indent_level -= jsonc->indent_increment;
|
||||||
if (!json_new_line(json))
|
if (!json_new_line(jsonc))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
if (!json_append_buf(json, "]"))
|
if (!json_append_buf(jsonc, "]"))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
|
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
sudo_json_add_value_int(struct json_container *json, const char *name,
|
sudo_json_add_value_int(struct json_container *jsonc, const char *name,
|
||||||
struct json_value *value, bool as_object)
|
struct json_value *value, bool as_object)
|
||||||
{
|
{
|
||||||
char numbuf[(((sizeof(long long) * 8) + 2) / 3) + 2];
|
char numbuf[(((sizeof(long long) * 8) + 2) / 3) + 2];
|
||||||
debug_decl(sudo_json_add_value, SUDO_DEBUG_UTIL);
|
debug_decl(sudo_json_add_value, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
/* Add comma if we are continuing an object/array. */
|
/* Add comma if we are continuing an object/array. */
|
||||||
if (json->need_comma) {
|
if (jsonc->need_comma) {
|
||||||
if (!json_append_buf(json, ","))
|
if (!json_append_buf(jsonc, ","))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
if (!json_new_line(json))
|
if (!json_new_line(jsonc))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
json->need_comma = true;
|
jsonc->need_comma = true;
|
||||||
|
|
||||||
if (as_object) {
|
if (as_object) {
|
||||||
if (!json_append_buf(json, json->minimal ? "{" : "{ "))
|
if (!json_append_buf(jsonc, jsonc->minimal ? "{" : "{ "))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* name */
|
/* name */
|
||||||
if (name != NULL) {
|
if (name != NULL) {
|
||||||
if (!json_append_string(json, name))
|
if (!json_append_string(jsonc, name))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
if (!json_append_buf(json, json->minimal ? ":" : ": "))
|
if (!json_append_buf(jsonc, jsonc->minimal ? ":" : ": "))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* value */
|
/* value */
|
||||||
switch (value->type) {
|
switch (value->type) {
|
||||||
case JSON_STRING:
|
case JSON_STRING:
|
||||||
if (!json_append_string(json, value->u.string))
|
if (!json_append_string(jsonc, value->u.string))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
break;
|
break;
|
||||||
case JSON_ID:
|
case JSON_ID:
|
||||||
snprintf(numbuf, sizeof(numbuf), "%u", (unsigned int)value->u.id);
|
snprintf(numbuf, sizeof(numbuf), "%u", (unsigned int)value->u.id);
|
||||||
if (!json_append_buf(json, numbuf))
|
if (!json_append_buf(jsonc, numbuf))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
break;
|
break;
|
||||||
case JSON_NUMBER:
|
case JSON_NUMBER:
|
||||||
snprintf(numbuf, sizeof(numbuf), "%lld", value->u.number);
|
snprintf(numbuf, sizeof(numbuf), "%lld", value->u.number);
|
||||||
if (!json_append_buf(json, numbuf))
|
if (!json_append_buf(jsonc, numbuf))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
break;
|
break;
|
||||||
case JSON_NULL:
|
case JSON_NULL:
|
||||||
if (!json_append_buf(json, "null"))
|
if (!json_append_buf(jsonc, "null"))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
break;
|
break;
|
||||||
case JSON_BOOL:
|
case JSON_BOOL:
|
||||||
if (!json_append_buf(json, value->u.boolean ? "true" : "false"))
|
if (!json_append_buf(jsonc, value->u.boolean ? "true" : "false"))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
break;
|
break;
|
||||||
case JSON_ARRAY:
|
case JSON_ARRAY:
|
||||||
@@ -354,7 +354,7 @@ sudo_json_add_value_int(struct json_container *json, const char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (as_object) {
|
if (as_object) {
|
||||||
if (!json_append_buf(json, json->minimal ? "}" : " }"))
|
if (!json_append_buf(jsonc, jsonc->minimal ? "}" : " }"))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,27 +362,27 @@ sudo_json_add_value_int(struct json_container *json, const char *name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sudo_json_add_value_v1(struct json_container *json, const char *name,
|
sudo_json_add_value_v1(struct json_container *jsonc, const char *name,
|
||||||
struct json_value *value)
|
struct json_value *value)
|
||||||
{
|
{
|
||||||
return sudo_json_add_value_int(json, name, value, false);
|
return sudo_json_add_value_int(jsonc, name, value, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sudo_json_add_value_as_object_v1(struct json_container *json, const char *name,
|
sudo_json_add_value_as_object_v1(struct json_container *jsonc, const char *name,
|
||||||
struct json_value *value)
|
struct json_value *value)
|
||||||
{
|
{
|
||||||
return sudo_json_add_value_int(json, name, value, true);
|
return sudo_json_add_value_int(jsonc, name, value, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
sudo_json_get_buf_v1(struct json_container *json)
|
sudo_json_get_buf_v1(struct json_container *jsonc)
|
||||||
{
|
{
|
||||||
return json->buf;
|
return jsonc->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int
|
unsigned int
|
||||||
sudo_json_get_len_v1(struct json_container *json)
|
sudo_json_get_len_v1(struct json_container *jsonc)
|
||||||
{
|
{
|
||||||
return json->buflen;
|
return jsonc->buflen;
|
||||||
}
|
}
|
||||||
|
@@ -87,7 +87,7 @@ set_random_drop(const char *dropstr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
logsrvd_json_log_cb(struct json_container *json, void *v)
|
logsrvd_json_log_cb(struct json_container *jsonc, void *v)
|
||||||
{
|
{
|
||||||
struct logsrvd_info_closure *closure = v;
|
struct logsrvd_info_closure *closure = v;
|
||||||
struct json_value json_value;
|
struct json_value json_value;
|
||||||
@@ -101,7 +101,7 @@ logsrvd_json_log_cb(struct json_container *json, void *v)
|
|||||||
case INFO_MESSAGE__VALUE_NUMVAL:
|
case INFO_MESSAGE__VALUE_NUMVAL:
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = info->u.numval;
|
json_value.u.number = info->u.numval;
|
||||||
if (!sudo_json_add_value(json, info->key, &json_value))
|
if (!sudo_json_add_value(jsonc, info->key, &json_value))
|
||||||
goto bad;
|
goto bad;
|
||||||
break;
|
break;
|
||||||
case INFO_MESSAGE__VALUE_STRVAL:
|
case INFO_MESSAGE__VALUE_STRVAL:
|
||||||
@@ -112,7 +112,7 @@ logsrvd_json_log_cb(struct json_container *json, void *v)
|
|||||||
}
|
}
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = info->u.strval;
|
json_value.u.string = info->u.strval;
|
||||||
if (!sudo_json_add_value(json, info->key, &json_value))
|
if (!sudo_json_add_value(jsonc, info->key, &json_value))
|
||||||
goto bad;
|
goto bad;
|
||||||
break;
|
break;
|
||||||
case INFO_MESSAGE__VALUE_STRLISTVAL: {
|
case INFO_MESSAGE__VALUE_STRLISTVAL: {
|
||||||
@@ -124,7 +124,7 @@ logsrvd_json_log_cb(struct json_container *json, void *v)
|
|||||||
"local", info->key);
|
"local", info->key);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!sudo_json_open_array(json, info->key))
|
if (!sudo_json_open_array(jsonc, info->key))
|
||||||
goto bad;
|
goto bad;
|
||||||
for (n = 0; n < strlist->n_strings; n++) {
|
for (n = 0; n < strlist->n_strings; n++) {
|
||||||
if (strlist->strings[n] == NULL) {
|
if (strlist->strings[n] == NULL) {
|
||||||
@@ -134,10 +134,10 @@ logsrvd_json_log_cb(struct json_container *json, void *v)
|
|||||||
}
|
}
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = strlist->strings[n];
|
json_value.u.string = strlist->strings[n];
|
||||||
if (!sudo_json_add_value(json, NULL, &json_value))
|
if (!sudo_json_add_value(jsonc, NULL, &json_value))
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
if (!sudo_json_close_array(json))
|
if (!sudo_json_close_array(jsonc))
|
||||||
goto bad;
|
goto bad;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -150,15 +150,15 @@ logsrvd_json_log_cb(struct json_container *json, void *v)
|
|||||||
"local", info->key);
|
"local", info->key);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!sudo_json_open_array(json, info->key))
|
if (!sudo_json_open_array(jsonc, info->key))
|
||||||
goto bad;
|
goto bad;
|
||||||
for (n = 0; n < numlist->n_numbers; n++) {
|
for (n = 0; n < numlist->n_numbers; n++) {
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = numlist->numbers[n];
|
json_value.u.number = numlist->numbers[n];
|
||||||
if (!sudo_json_add_value(json, NULL, &json_value))
|
if (!sudo_json_add_value(jsonc, NULL, &json_value))
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
if (!sudo_json_close_array(json))
|
if (!sudo_json_close_array(jsonc))
|
||||||
goto bad;
|
goto bad;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -304,7 +304,7 @@ done:
|
|||||||
static bool
|
static bool
|
||||||
store_exit_info_json(int dfd, struct eventlog *evlog)
|
store_exit_info_json(int dfd, struct eventlog *evlog)
|
||||||
{
|
{
|
||||||
struct json_container json = { 0 };
|
struct json_container jsonc = { 0 };
|
||||||
struct json_value json_value;
|
struct json_value json_value;
|
||||||
struct iovec iov[3];
|
struct iovec iov[3];
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
@@ -312,7 +312,7 @@ store_exit_info_json(int dfd, struct eventlog *evlog)
|
|||||||
off_t pos;
|
off_t pos;
|
||||||
debug_decl(store_exit_info_json, SUDO_DEBUG_UTIL);
|
debug_decl(store_exit_info_json, SUDO_DEBUG_UTIL);
|
||||||
|
|
||||||
if (!sudo_json_init(&json, 4, false, false))
|
if (!sudo_json_init(&jsonc, 4, false, false))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
fd = iolog_openat(dfd, "log.json", O_RDWR);
|
fd = iolog_openat(dfd, "log.json", O_RDWR);
|
||||||
@@ -327,38 +327,38 @@ store_exit_info_json(int dfd, struct eventlog *evlog)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sudo_timespecisset(&evlog->run_time)) {
|
if (sudo_timespecisset(&evlog->run_time)) {
|
||||||
if (!sudo_json_open_object(&json, "run_time"))
|
if (!sudo_json_open_object(&jsonc, "run_time"))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = evlog->run_time.tv_sec;
|
json_value.u.number = evlog->run_time.tv_sec;
|
||||||
if (!sudo_json_add_value(&json, "seconds", &json_value))
|
if (!sudo_json_add_value(&jsonc, "seconds", &json_value))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = evlog->run_time.tv_nsec;
|
json_value.u.number = evlog->run_time.tv_nsec;
|
||||||
if (!sudo_json_add_value(&json, "nanoseconds", &json_value))
|
if (!sudo_json_add_value(&jsonc, "nanoseconds", &json_value))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (!sudo_json_close_object(&json))
|
if (!sudo_json_close_object(&jsonc))
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evlog->signal_name != NULL) {
|
if (evlog->signal_name != NULL) {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = evlog->signal_name;
|
json_value.u.string = evlog->signal_name;
|
||||||
if (!sudo_json_add_value(&json, "signal", &json_value))
|
if (!sudo_json_add_value(&jsonc, "signal", &json_value))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
json_value.type = JSON_BOOL;
|
json_value.type = JSON_BOOL;
|
||||||
json_value.u.boolean = evlog->dumped_core;
|
json_value.u.boolean = evlog->dumped_core;
|
||||||
if (!sudo_json_add_value(&json, "dumped_core", &json_value))
|
if (!sudo_json_add_value(&jsonc, "dumped_core", &json_value))
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = evlog->exit_value;
|
json_value.u.number = evlog->exit_value;
|
||||||
if (!sudo_json_add_value(&json, "exit_value", &json_value))
|
if (!sudo_json_add_value(&jsonc, "exit_value", &json_value))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
/* Back up to overwrite the final "\n}\n" */
|
/* Back up to overwrite the final "\n}\n" */
|
||||||
@@ -372,8 +372,8 @@ store_exit_info_json(int dfd, struct eventlog *evlog)
|
|||||||
/* Append the exit data and close the object. */
|
/* Append the exit data and close the object. */
|
||||||
iov[0].iov_base = (char *)",";
|
iov[0].iov_base = (char *)",";
|
||||||
iov[0].iov_len = 1;
|
iov[0].iov_len = 1;
|
||||||
iov[1].iov_base = sudo_json_get_buf(&json);
|
iov[1].iov_base = sudo_json_get_buf(&jsonc);
|
||||||
iov[1].iov_len = sudo_json_get_len(&json);
|
iov[1].iov_len = sudo_json_get_len(&jsonc);
|
||||||
iov[2].iov_base = (char *)"\n}\n";
|
iov[2].iov_base = (char *)"\n}\n";
|
||||||
iov[2].iov_len = 3;
|
iov[2].iov_len = 3;
|
||||||
if (writev(fd, iov, 3) == -1) {
|
if (writev(fd, iov, 3) == -1) {
|
||||||
@@ -391,7 +391,7 @@ store_exit_info_json(int dfd, struct eventlog *evlog)
|
|||||||
done:
|
done:
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
close(fd);
|
close(fd);
|
||||||
sudo_json_free(&json);
|
sudo_json_free(&jsonc);
|
||||||
debug_return_bool(ret);
|
debug_return_bool(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -189,7 +189,7 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
add_key_value(struct json_container *json, const char *str)
|
add_key_value(struct json_container *jsonc, const char *str)
|
||||||
{
|
{
|
||||||
struct json_value json_value;
|
struct json_value json_value;
|
||||||
const char *cp, *errstr;
|
const char *cp, *errstr;
|
||||||
@@ -256,26 +256,26 @@ add_key_value(struct json_container *json, const char *str)
|
|||||||
json_value.u.string = cp;
|
json_value.u.string = cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_return_bool(sudo_json_add_value(json, name, &json_value));
|
debug_return_bool(sudo_json_add_value(jsonc, name, &json_value));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
add_array(struct json_container *json, const char *name, char * const * array)
|
add_array(struct json_container *jsonc, const char *name, char * const * array)
|
||||||
{
|
{
|
||||||
const char *cp;
|
const char *cp;
|
||||||
struct json_value json_value;
|
struct json_value json_value;
|
||||||
debug_decl(add_array, SUDO_DEBUG_PLUGIN);
|
debug_decl(add_array, SUDO_DEBUG_PLUGIN);
|
||||||
|
|
||||||
if (!sudo_json_open_array(json, name))
|
if (!sudo_json_open_array(jsonc, name))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
while ((cp = *array) != NULL) {
|
while ((cp = *array) != NULL) {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = cp;
|
json_value.u.string = cp;
|
||||||
if (!sudo_json_add_value(json, name, &json_value))
|
if (!sudo_json_add_value(jsonc, name, &json_value))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
array++;
|
array++;
|
||||||
}
|
}
|
||||||
if (!sudo_json_close_array(json))
|
if (!sudo_json_close_array(jsonc))
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
|
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
@@ -299,7 +299,7 @@ filter_key_value(const char *kv, const char * const * filter)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
add_key_value_object(struct json_container *json, const char *name,
|
add_key_value_object(struct json_container *jsonc, const char *name,
|
||||||
char * const * array, const char * const * filter)
|
char * const * array, const char * const * filter)
|
||||||
{
|
{
|
||||||
char * const *cur;
|
char * const *cur;
|
||||||
@@ -318,15 +318,15 @@ add_key_value_object(struct json_container *json, const char *name,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!empty) {
|
if (!empty) {
|
||||||
if (!sudo_json_open_object(json, name))
|
if (!sudo_json_open_object(jsonc, name))
|
||||||
goto bad;
|
goto bad;
|
||||||
for (cur = array; (cp = *cur) != NULL; cur++) {
|
for (cur = array; (cp = *cur) != NULL; cur++) {
|
||||||
if (filter_key_value(cp, filter))
|
if (filter_key_value(cp, filter))
|
||||||
continue;
|
continue;
|
||||||
if (!add_key_value(json, cp))
|
if (!add_key_value(jsonc, cp))
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
if (!sudo_json_close_object(json))
|
if (!sudo_json_close_object(jsonc))
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +336,7 @@ bad:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
add_timestamp(struct json_container *json, struct timespec *ts)
|
add_timestamp(struct json_container *jsonc, struct timespec *ts)
|
||||||
{
|
{
|
||||||
struct json_value json_value;
|
struct json_value json_value;
|
||||||
time_t secs = ts->tv_sec;
|
time_t secs = ts->tv_sec;
|
||||||
@@ -348,22 +348,22 @@ add_timestamp(struct json_container *json, struct timespec *ts)
|
|||||||
if (gmtime_r(&secs, &gmt) == NULL)
|
if (gmtime_r(&secs, &gmt) == NULL)
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
|
|
||||||
sudo_json_open_object(json, "timestamp");
|
sudo_json_open_object(jsonc, "timestamp");
|
||||||
|
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = ts->tv_sec;
|
json_value.u.number = ts->tv_sec;
|
||||||
sudo_json_add_value(json, "seconds", &json_value);
|
sudo_json_add_value(jsonc, "seconds", &json_value);
|
||||||
|
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = ts->tv_nsec;
|
json_value.u.number = ts->tv_nsec;
|
||||||
sudo_json_add_value(json, "nanoseconds", &json_value);
|
sudo_json_add_value(jsonc, "nanoseconds", &json_value);
|
||||||
|
|
||||||
timebuf[sizeof(timebuf) - 1] = '\0';
|
timebuf[sizeof(timebuf) - 1] = '\0';
|
||||||
len = strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", &gmt);
|
len = strftime(timebuf, sizeof(timebuf), "%Y%m%d%H%M%SZ", &gmt);
|
||||||
if (len != 0 && timebuf[sizeof(timebuf) - 1] == '\0'){
|
if (len != 0 && timebuf[sizeof(timebuf) - 1] == '\0'){
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = timebuf;
|
json_value.u.string = timebuf;
|
||||||
sudo_json_add_value(json, "iso8601", &json_value);
|
sudo_json_add_value(jsonc, "iso8601", &json_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
timebuf[sizeof(timebuf) - 1] = '\0';
|
timebuf[sizeof(timebuf) - 1] = '\0';
|
||||||
@@ -371,16 +371,16 @@ add_timestamp(struct json_container *json, struct timespec *ts)
|
|||||||
if (len != 0 && timebuf[sizeof(timebuf) - 1] == '\0'){
|
if (len != 0 && timebuf[sizeof(timebuf) - 1] == '\0'){
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = timebuf;
|
json_value.u.string = timebuf;
|
||||||
sudo_json_add_value(json, "localtime", &json_value);
|
sudo_json_add_value(jsonc, "localtime", &json_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
sudo_json_close_object(json);
|
sudo_json_close_object(jsonc);
|
||||||
|
|
||||||
debug_return_bool(true);
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
audit_write_json(struct json_container *json)
|
audit_write_json(struct json_container *jsonc)
|
||||||
{
|
{
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
@@ -410,7 +410,7 @@ audit_write_json(struct json_container *json)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
fputs(sudo_json_get_buf(json), state.log_fp);
|
fputs(sudo_json_get_buf(jsonc), state.log_fp);
|
||||||
fputs("\n}\n", state.log_fp);
|
fputs("\n}\n", state.log_fp);
|
||||||
fflush(state.log_fp);
|
fflush(state.log_fp);
|
||||||
(void)sudo_lock_file(fileno(state.log_fp), SUDO_UNLOCK);
|
(void)sudo_lock_file(fileno(state.log_fp), SUDO_UNLOCK);
|
||||||
@@ -426,7 +426,7 @@ done:
|
|||||||
static int
|
static int
|
||||||
audit_write_exit_record(int exit_status, int error)
|
audit_write_exit_record(int exit_status, int error)
|
||||||
{
|
{
|
||||||
struct json_container json;
|
struct json_container jsonc;
|
||||||
struct json_value json_value;
|
struct json_value json_value;
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
@@ -437,33 +437,33 @@ audit_write_exit_record(int exit_status, int error)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sudo_json_init(&json, 4, false, false))
|
if (!sudo_json_init(&jsonc, 4, false, false))
|
||||||
goto oom;
|
goto oom;
|
||||||
if (!sudo_json_open_object(&json, "exit"))
|
if (!sudo_json_open_object(&jsonc, "exit"))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
/* Write UUID */
|
/* Write UUID */
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = state.uuid_str;
|
json_value.u.string = state.uuid_str;
|
||||||
if (!sudo_json_add_value(&json, "uuid", &json_value))
|
if (!sudo_json_add_value(&jsonc, "uuid", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
/* Write time stamp */
|
/* Write time stamp */
|
||||||
if (!add_timestamp(&json, &now))
|
if (!add_timestamp(&jsonc, &now))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
if (error != 0) {
|
if (error != 0) {
|
||||||
/* Error executing command */
|
/* Error executing command */
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = strerror(error);
|
json_value.u.string = strerror(error);
|
||||||
if (!sudo_json_add_value(&json, "error", &json_value))
|
if (!sudo_json_add_value(&jsonc, "error", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
} else {
|
} else {
|
||||||
if (WIFEXITED(exit_status)) {
|
if (WIFEXITED(exit_status)) {
|
||||||
/* Command exited normally. */
|
/* Command exited normally. */
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = WEXITSTATUS(exit_status);
|
json_value.u.number = WEXITSTATUS(exit_status);
|
||||||
if (!sudo_json_add_value(&json, "exit_value", &json_value))
|
if (!sudo_json_add_value(&jsonc, "exit_value", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
} else if (WIFSIGNALED(exit_status)) {
|
} else if (WIFSIGNALED(exit_status)) {
|
||||||
/* Command killed by signal. */
|
/* Command killed by signal. */
|
||||||
@@ -472,37 +472,37 @@ audit_write_exit_record(int exit_status, int error)
|
|||||||
if (signo <= 0 || sig2str(signo, signame) == -1) {
|
if (signo <= 0 || sig2str(signo, signame) == -1) {
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = signo;
|
json_value.u.number = signo;
|
||||||
if (!sudo_json_add_value(&json, "signal", &json_value))
|
if (!sudo_json_add_value(&jsonc, "signal", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
} else {
|
} else {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = signame; // -V507
|
json_value.u.string = signame; // -V507
|
||||||
if (!sudo_json_add_value(&json, "signal", &json_value))
|
if (!sudo_json_add_value(&jsonc, "signal", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
/* Core dump? */
|
/* Core dump? */
|
||||||
json_value.type = JSON_BOOL;
|
json_value.type = JSON_BOOL;
|
||||||
json_value.u.boolean = WCOREDUMP(exit_status);
|
json_value.u.boolean = WCOREDUMP(exit_status);
|
||||||
if (!sudo_json_add_value(&json, "dumped_core", &json_value))
|
if (!sudo_json_add_value(&jsonc, "dumped_core", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
/* Exit value */
|
/* Exit value */
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = WTERMSIG(exit_status) | 128;
|
json_value.u.number = WTERMSIG(exit_status) | 128;
|
||||||
if (!sudo_json_add_value(&json, "exit_value", &json_value))
|
if (!sudo_json_add_value(&jsonc, "exit_value", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sudo_json_close_object(&json))
|
if (!sudo_json_close_object(&jsonc))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
ret = audit_write_json(&json);
|
ret = audit_write_json(&jsonc);
|
||||||
sudo_json_free(&json);
|
sudo_json_free(&jsonc);
|
||||||
done:
|
done:
|
||||||
debug_return_int(ret);
|
debug_return_int(ret);
|
||||||
oom:
|
oom:
|
||||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||||
sudo_json_free(&json);
|
sudo_json_free(&jsonc);
|
||||||
debug_return_int(-1);
|
debug_return_int(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,7 +511,7 @@ audit_write_record(const char *audit_str, const char *plugin_name,
|
|||||||
unsigned int plugin_type, const char *reason, char * const command_info[],
|
unsigned int plugin_type, const char *reason, char * const command_info[],
|
||||||
char * const run_argv[], char * const run_envp[])
|
char * const run_argv[], char * const run_envp[])
|
||||||
{
|
{
|
||||||
struct json_container json;
|
struct json_container jsonc;
|
||||||
struct json_value json_value;
|
struct json_value json_value;
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
@@ -522,14 +522,14 @@ audit_write_record(const char *audit_str, const char *plugin_name,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sudo_json_init(&json, 4, false, false))
|
if (!sudo_json_init(&jsonc, 4, false, false))
|
||||||
goto oom;
|
goto oom;
|
||||||
if (!sudo_json_open_object(&json, audit_str))
|
if (!sudo_json_open_object(&jsonc, audit_str))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = plugin_name;
|
json_value.u.string = plugin_name;
|
||||||
if (!sudo_json_add_value(&json, "plugin_name", &json_value))
|
if (!sudo_json_add_value(&jsonc, "plugin_name", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
switch (plugin_type) {
|
switch (plugin_type) {
|
||||||
@@ -553,85 +553,85 @@ audit_write_record(const char *audit_str, const char *plugin_name,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
if (!sudo_json_add_value(&json, "plugin_type", &json_value))
|
if (!sudo_json_add_value(&jsonc, "plugin_type", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
/* error and reject audit events usually contain a reason. */
|
/* error and reject audit events usually contain a reason. */
|
||||||
if (reason != NULL) {
|
if (reason != NULL) {
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = reason;
|
json_value.u.string = reason;
|
||||||
if (!sudo_json_add_value(&json, "reason", &json_value))
|
if (!sudo_json_add_value(&jsonc, "reason", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
|
||||||
json_value.type = JSON_STRING;
|
json_value.type = JSON_STRING;
|
||||||
json_value.u.string = state.uuid_str;
|
json_value.u.string = state.uuid_str;
|
||||||
if (!sudo_json_add_value(&json, "uuid", &json_value))
|
if (!sudo_json_add_value(&jsonc, "uuid", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
if (!add_timestamp(&json, &now))
|
if (!add_timestamp(&jsonc, &now))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
/* Write key=value objects. */
|
/* Write key=value objects. */
|
||||||
if (state.settings != NULL) {
|
if (state.settings != NULL) {
|
||||||
if (!add_key_value_object(&json, "options", state.settings, settings_filter))
|
if (!add_key_value_object(&jsonc, "options", state.settings, settings_filter))
|
||||||
goto oom;
|
goto oom;
|
||||||
} else {
|
} else {
|
||||||
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
|
||||||
"missing settings list");
|
"missing settings list");
|
||||||
}
|
}
|
||||||
if (state.user_info != NULL) {
|
if (state.user_info != NULL) {
|
||||||
if (!add_key_value_object(&json, "user_info", state.user_info, NULL))
|
if (!add_key_value_object(&jsonc, "user_info", state.user_info, NULL))
|
||||||
goto oom;
|
goto oom;
|
||||||
} else {
|
} else {
|
||||||
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
|
||||||
"missing user_info list");
|
"missing user_info list");
|
||||||
}
|
}
|
||||||
if (command_info != NULL) {
|
if (command_info != NULL) {
|
||||||
if (!add_key_value_object(&json, "command_info", command_info, NULL))
|
if (!add_key_value_object(&jsonc, "command_info", command_info, NULL))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write submit_optind before submit_argv */
|
/* Write submit_optind before submit_argv */
|
||||||
json_value.type = JSON_NUMBER;
|
json_value.type = JSON_NUMBER;
|
||||||
json_value.u.number = state.submit_optind;
|
json_value.u.number = state.submit_optind;
|
||||||
if (!sudo_json_add_value(&json, "submit_optind", &json_value))
|
if (!sudo_json_add_value(&jsonc, "submit_optind", &json_value))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
if (state.submit_argv != NULL) {
|
if (state.submit_argv != NULL) {
|
||||||
if (!add_array(&json, "submit_argv", state.submit_argv))
|
if (!add_array(&jsonc, "submit_argv", state.submit_argv))
|
||||||
goto oom;
|
goto oom;
|
||||||
} else {
|
} else {
|
||||||
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
|
||||||
"missing submit_argv array");
|
"missing submit_argv array");
|
||||||
}
|
}
|
||||||
if (state.submit_envp != NULL) {
|
if (state.submit_envp != NULL) {
|
||||||
if (!add_array(&json, "submit_envp", state.submit_envp))
|
if (!add_array(&jsonc, "submit_envp", state.submit_envp))
|
||||||
goto oom;
|
goto oom;
|
||||||
} else {
|
} else {
|
||||||
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO,
|
||||||
"missing submit_envp array");
|
"missing submit_envp array");
|
||||||
}
|
}
|
||||||
if (run_argv != NULL) {
|
if (run_argv != NULL) {
|
||||||
if (!add_array(&json, "run_argv", run_argv))
|
if (!add_array(&jsonc, "run_argv", run_argv))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
if (run_envp != NULL) {
|
if (run_envp != NULL) {
|
||||||
if (!add_array(&json, "run_envp", run_envp))
|
if (!add_array(&jsonc, "run_envp", run_envp))
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sudo_json_close_object(&json))
|
if (!sudo_json_close_object(&jsonc))
|
||||||
goto oom;
|
goto oom;
|
||||||
|
|
||||||
ret = audit_write_json(&json);
|
ret = audit_write_json(&jsonc);
|
||||||
sudo_json_free(&json);
|
sudo_json_free(&jsonc);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
debug_return_int(ret);
|
debug_return_int(ret);
|
||||||
oom:
|
oom:
|
||||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||||
sudo_json_free(&json);
|
sudo_json_free(&jsonc);
|
||||||
debug_return_int(-1);
|
debug_return_int(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -413,7 +413,7 @@ int sudoers_hook_getenv(const char *name, char **value, void *closure);
|
|||||||
int sudoers_hook_putenv(char *string, void *closure);
|
int sudoers_hook_putenv(char *string, void *closure);
|
||||||
int sudoers_hook_setenv(const char *name, const char *value, int overwrite, void *closure);
|
int sudoers_hook_setenv(const char *name, const char *value, int overwrite, void *closure);
|
||||||
int sudoers_hook_unsetenv(const char *name, void *closure);
|
int sudoers_hook_unsetenv(const char *name, void *closure);
|
||||||
void register_env_file(void * (*ef_open)(const char *), void (*ef_close)(void *), char * (*ef_next)(void *, int *), bool system);
|
void register_env_file(void * (*ef_open)(const char *), void (*ef_close)(void *), char * (*ef_next)(void *, int *), bool sys);
|
||||||
|
|
||||||
/* env_pattern.c */
|
/* env_pattern.c */
|
||||||
bool matches_env_pattern(const char *pattern, const char *var, bool *full_match);
|
bool matches_env_pattern(const char *pattern, const char *var, bool *full_match);
|
||||||
|
@@ -57,7 +57,9 @@ getenv_unhooked(const char *name)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
sudo_dso_public char *
|
sudo_dso_public char *getenv(const char *name);
|
||||||
|
|
||||||
|
char *
|
||||||
getenv(const char *name)
|
getenv(const char *name)
|
||||||
{
|
{
|
||||||
char *val = NULL;
|
char *val = NULL;
|
||||||
@@ -143,7 +145,9 @@ putenv_unhooked(PUTENV_CONST char *string)
|
|||||||
return rpl_putenv(string);
|
return rpl_putenv(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
sudo_dso_public int
|
sudo_dso_public int putenv(PUTENV_CONST char *string);
|
||||||
|
|
||||||
|
int
|
||||||
putenv(PUTENV_CONST char *string)
|
putenv(PUTENV_CONST char *string)
|
||||||
{
|
{
|
||||||
switch (process_hooks_putenv((char *)string)) {
|
switch (process_hooks_putenv((char *)string)) {
|
||||||
@@ -215,7 +219,9 @@ setenv_unhooked(const char *var, const char *val, int overwrite)
|
|||||||
return rpl_setenv(var, val, overwrite);
|
return rpl_setenv(var, val, overwrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
sudo_dso_public int
|
sudo_dso_public int setenv(const char *var, const char *val, int overwrite);
|
||||||
|
|
||||||
|
int
|
||||||
setenv(const char *var, const char *val, int overwrite)
|
setenv(const char *var, const char *val, int overwrite)
|
||||||
{
|
{
|
||||||
switch (process_hooks_setenv(var, val, overwrite)) {
|
switch (process_hooks_setenv(var, val, overwrite)) {
|
||||||
@@ -280,10 +286,14 @@ unsetenv_unhooked(const char *var)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef UNSETENV_VOID
|
#ifdef UNSETENV_VOID
|
||||||
sudo_dso_public void
|
# define UNSETENV_RTYPE void
|
||||||
#else
|
#else
|
||||||
sudo_dso_public int
|
# define UNSETENV_RTYPE int
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
sudo_dso_public UNSETENV_RTYPE unsetenv(const char *var);
|
||||||
|
|
||||||
|
UNSETENV_RTYPE
|
||||||
unsetenv(const char *var)
|
unsetenv(const char *var)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@@ -218,8 +218,8 @@ intercept_cleanup(void)
|
|||||||
static bool
|
static bool
|
||||||
prepare_listener(struct intercept_closure *closure)
|
prepare_listener(struct intercept_closure *closure)
|
||||||
{
|
{
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin4;
|
||||||
socklen_t sin_len = sizeof(sin);
|
socklen_t sin4_len = sizeof(sin4);
|
||||||
int sock;
|
int sock;
|
||||||
debug_decl(prepare_listener, SUDO_DEBUG_EXEC);
|
debug_decl(prepare_listener, SUDO_DEBUG_EXEC);
|
||||||
|
|
||||||
@@ -234,15 +234,15 @@ prepare_listener(struct intercept_closure *closure)
|
|||||||
sudo_warn("socket");
|
sudo_warn("socket");
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
memset(&sin, 0, sizeof(sin));
|
memset(&sin4, 0, sizeof(sin4));
|
||||||
sin.sin_family = AF_INET;
|
sin4.sin_family = AF_INET;
|
||||||
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
sin4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
sin.sin_port = 0;
|
sin4.sin_port = 0;
|
||||||
if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
|
if (bind(sock, (struct sockaddr *)&sin4, sizeof(sin4)) == -1) {
|
||||||
sudo_warn("bind");
|
sudo_warn("bind");
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
if (getsockname(sock, (struct sockaddr *)&sin, &sin_len) == -1) {
|
if (getsockname(sock, (struct sockaddr *)&sin4, &sin4_len) == -1) {
|
||||||
sudo_warn("getsockname");
|
sudo_warn("getsockname");
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@@ -252,7 +252,7 @@ prepare_listener(struct intercept_closure *closure)
|
|||||||
}
|
}
|
||||||
|
|
||||||
closure->listen_sock = sock;
|
closure->listen_sock = sock;
|
||||||
intercept_listen_port = ntohs(sin.sin_port);
|
intercept_listen_port = ntohs(sin4.sin_port);
|
||||||
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
|
||||||
"%s: listening on port %hu", __func__, intercept_listen_port);
|
"%s: listening on port %hu", __func__, intercept_listen_port);
|
||||||
|
|
||||||
@@ -1012,8 +1012,8 @@ intercept_accept_cb(int fd, int what, void *v)
|
|||||||
{
|
{
|
||||||
struct intercept_closure *closure = v;
|
struct intercept_closure *closure = v;
|
||||||
struct sudo_event_base *evbase = sudo_ev_get_base(&closure->ev);
|
struct sudo_event_base *evbase = sudo_ev_get_base(&closure->ev);
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin4;
|
||||||
socklen_t sin_len = sizeof(sin);
|
socklen_t sin4_len = sizeof(sin4);
|
||||||
int client_sock, flags, on = 1;
|
int client_sock, flags, on = 1;
|
||||||
debug_decl(intercept_accept_cb, SUDO_DEBUG_EXEC);
|
debug_decl(intercept_accept_cb, SUDO_DEBUG_EXEC);
|
||||||
|
|
||||||
@@ -1026,7 +1026,7 @@ intercept_accept_cb(int fd, int what, void *v)
|
|||||||
debug_return;
|
debug_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
client_sock = accept(fd, (struct sockaddr *)&sin, &sin_len);
|
client_sock = accept(fd, (struct sockaddr *)&sin4, &sin4_len);
|
||||||
if (client_sock == -1) {
|
if (client_sock == -1) {
|
||||||
sudo_warn("accept");
|
sudo_warn("accept");
|
||||||
goto bad;
|
goto bad;
|
||||||
|
@@ -105,7 +105,7 @@ int
|
|||||||
get_net_ifs(char **addrinfo_out)
|
get_net_ifs(char **addrinfo_out)
|
||||||
{
|
{
|
||||||
struct ifaddrs *ifa, *ifaddrs;
|
struct ifaddrs *ifa, *ifaddrs;
|
||||||
struct sockaddr_in *sin;
|
struct sockaddr_in *sin4;
|
||||||
# ifdef HAVE_STRUCT_IN6_ADDR
|
# ifdef HAVE_STRUCT_IN6_ADDR
|
||||||
struct sockaddr_in6 *sin6;
|
struct sockaddr_in6 *sin6;
|
||||||
# endif
|
# endif
|
||||||
@@ -156,19 +156,19 @@ get_net_ifs(char **addrinfo_out)
|
|||||||
|
|
||||||
switch (ifa->ifa_addr->sa_family) {
|
switch (ifa->ifa_addr->sa_family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
sin = (struct sockaddr_in *)ifa->ifa_addr;
|
sin4 = (struct sockaddr_in *)ifa->ifa_addr;
|
||||||
if (sin->sin_addr.s_addr == INADDR_ANY || sin->sin_addr.s_addr == INADDR_NONE) {
|
if (sin4->sin_addr.s_addr == INADDR_ANY || sin4->sin_addr.s_addr == INADDR_NONE) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"ignoring unspecified AF_INET addr for %s", ifa->ifa_name);
|
"ignoring unspecified AF_INET addr for %s", ifa->ifa_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (inet_ntop(AF_INET, &sin->sin_addr, addrstr, sizeof(addrstr)) == NULL) {
|
if (inet_ntop(AF_INET, &sin4->sin_addr, addrstr, sizeof(addrstr)) == NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"ignoring bad AF_INET addr for %s", ifa->ifa_name);
|
"ignoring bad AF_INET addr for %s", ifa->ifa_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
sin = (struct sockaddr_in *)ifa->ifa_netmask;
|
sin4 = (struct sockaddr_in *)ifa->ifa_netmask;
|
||||||
if (inet_ntop(AF_INET, &sin->sin_addr, maskstr, sizeof(maskstr)) == NULL) {
|
if (inet_ntop(AF_INET, &sin4->sin_addr, maskstr, sizeof(maskstr)) == NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"ignoring bad AF_INET mask for %s", ifa->ifa_name);
|
"ignoring bad AF_INET mask for %s", ifa->ifa_name);
|
||||||
continue;
|
continue;
|
||||||
@@ -315,7 +315,7 @@ get_net_ifs(char **addrinfo_out)
|
|||||||
*/
|
*/
|
||||||
for (i = 0; i < ifconf.ifc_len; ) {
|
for (i = 0; i < ifconf.ifc_len; ) {
|
||||||
struct ifreq *ifr = (struct ifreq *)&ifconf.ifc_buf[i];
|
struct ifreq *ifr = (struct ifreq *)&ifconf.ifc_buf[i];
|
||||||
struct sockaddr_in *sin;
|
struct sockaddr_in *sin4;
|
||||||
|
|
||||||
/* Set i to the subscript of the next interface (no sa_len). */
|
/* Set i to the subscript of the next interface (no sa_len). */
|
||||||
i += sizeof(struct ifreq);
|
i += sizeof(struct ifreq);
|
||||||
@@ -329,13 +329,13 @@ get_net_ifs(char **addrinfo_out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Store the address. */
|
/* Store the address. */
|
||||||
sin = (struct sockaddr_in *)&ifr->ifr_addr;
|
sin4 = (struct sockaddr_in *)&ifr->ifr_addr;
|
||||||
if (sin->sin_addr.s_addr == INADDR_ANY || sin->sin_addr.s_addr == INADDR_NONE) {
|
if (sin4->sin_addr.s_addr == INADDR_ANY || sin4->sin_addr.s_addr == INADDR_NONE) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"ignoring unspecified AF_INET addr for %s", ifr->ifr_name);
|
"ignoring unspecified AF_INET addr for %s", ifr->ifr_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (inet_ntop(AF_INET, &sin->sin_addr, addrstr, sizeof(addrstr)) == NULL) {
|
if (inet_ntop(AF_INET, &sin4->sin_addr, addrstr, sizeof(addrstr)) == NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"ignoring bad AF_INET addr for %s", ifr->ifr_name);
|
"ignoring bad AF_INET addr for %s", ifr->ifr_name);
|
||||||
continue;
|
continue;
|
||||||
@@ -359,8 +359,8 @@ get_net_ifs(char **addrinfo_out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Convert the mask to string form. */
|
/* Convert the mask to string form. */
|
||||||
sin = (struct sockaddr_in *)&ifr->ifr_addr;
|
sin4 = (struct sockaddr_in *)&ifr->ifr_addr;
|
||||||
if (inet_ntop(AF_INET, &sin->sin_addr, maskstr, sizeof(maskstr)) == NULL) {
|
if (inet_ntop(AF_INET, &sin4->sin_addr, maskstr, sizeof(maskstr)) == NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"ignoring bad AF_INET mask for %s", ifr->ifr_name);
|
"ignoring bad AF_INET mask for %s", ifr->ifr_name);
|
||||||
continue;
|
continue;
|
||||||
@@ -467,7 +467,7 @@ get_net_ifs(char **addrinfo_out)
|
|||||||
{
|
{
|
||||||
struct lifconf lifconf;
|
struct lifconf lifconf;
|
||||||
struct lifnum lifn;
|
struct lifnum lifn;
|
||||||
struct sockaddr_in *sin;
|
struct sockaddr_in *sin4;
|
||||||
struct sockaddr_in6 *sin6;
|
struct sockaddr_in6 *sin6;
|
||||||
char addrstr[INET6_ADDRSTRLEN], maskstr[INET6_ADDRSTRLEN];
|
char addrstr[INET6_ADDRSTRLEN], maskstr[INET6_ADDRSTRLEN];
|
||||||
char *addrinfo = NULL;
|
char *addrinfo = NULL;
|
||||||
@@ -540,13 +540,13 @@ get_net_ifs(char **addrinfo_out)
|
|||||||
/* Store the address. */
|
/* Store the address. */
|
||||||
switch (family) {
|
switch (family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
sin = (struct sockaddr_in *)&lifr->lifr_addr;
|
sin4 = (struct sockaddr_in *)&lifr->lifr_addr;
|
||||||
if (sin->sin_addr.s_addr == INADDR_ANY || sin->sin_addr.s_addr == INADDR_NONE) {
|
if (sin4->sin_addr.s_addr == INADDR_ANY || sin4->sin_addr.s_addr == INADDR_NONE) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"ignoring unspecified AF_INET addr for %s", lifr->lifr_name);
|
"ignoring unspecified AF_INET addr for %s", lifr->lifr_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (inet_ntop(AF_INET, &sin->sin_addr, addrstr, sizeof(addrstr)) == NULL) {
|
if (inet_ntop(AF_INET, &sin4->sin_addr, addrstr, sizeof(addrstr)) == NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"ignoring bad AF_INET addr for %s", lifr->lifr_name);
|
"ignoring bad AF_INET addr for %s", lifr->lifr_name);
|
||||||
continue;
|
continue;
|
||||||
@@ -592,8 +592,8 @@ get_net_ifs(char **addrinfo_out)
|
|||||||
}
|
}
|
||||||
switch (family) {
|
switch (family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
sin = (struct sockaddr_in *)&lifr->lifr_addr;
|
sin4 = (struct sockaddr_in *)&lifr->lifr_addr;
|
||||||
if (inet_ntop(AF_INET, &sin->sin_addr, maskstr, sizeof(maskstr)) == NULL) {
|
if (inet_ntop(AF_INET, &sin4->sin_addr, maskstr, sizeof(maskstr)) == NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"ignoring bad AF_INET mask for %s", lifr->lifr_name);
|
"ignoring bad AF_INET mask for %s", lifr->lifr_name);
|
||||||
continue;
|
continue;
|
||||||
@@ -654,7 +654,7 @@ get_net_ifs(char **addrinfo_out)
|
|||||||
{
|
{
|
||||||
struct ifconf ifconf;
|
struct ifconf ifconf;
|
||||||
struct ifreq *ifr;
|
struct ifreq *ifr;
|
||||||
struct sockaddr_in *sin;
|
struct sockaddr_in *sin4;
|
||||||
# ifdef HAVE_STRUCT_IN6_ADDR
|
# ifdef HAVE_STRUCT_IN6_ADDR
|
||||||
struct sockaddr_in6 *sin6;
|
struct sockaddr_in6 *sin6;
|
||||||
# endif
|
# endif
|
||||||
@@ -768,13 +768,13 @@ get_net_ifs(char **addrinfo_out)
|
|||||||
/* Store the address. */
|
/* Store the address. */
|
||||||
switch (family) {
|
switch (family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
sin = (struct sockaddr_in *)&ifr->ifr_addr;
|
sin4 = (struct sockaddr_in *)&ifr->ifr_addr;
|
||||||
if (sin->sin_addr.s_addr == INADDR_ANY || sin->sin_addr.s_addr == INADDR_NONE) {
|
if (sin4->sin_addr.s_addr == INADDR_ANY || sin4->sin_addr.s_addr == INADDR_NONE) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"ignoring unspecified AF_INET addr for %s", ifr->ifr_name);
|
"ignoring unspecified AF_INET addr for %s", ifr->ifr_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (inet_ntop(AF_INET, &sin->sin_addr, addrstr, sizeof(addrstr)) == NULL) {
|
if (inet_ntop(AF_INET, &sin4->sin_addr, addrstr, sizeof(addrstr)) == NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"ignoring bad AF_INET addr for %s", ifr->ifr_name);
|
"ignoring bad AF_INET addr for %s", ifr->ifr_name);
|
||||||
continue;
|
continue;
|
||||||
@@ -824,8 +824,8 @@ get_net_ifs(char **addrinfo_out)
|
|||||||
/* Convert the mask to string form. */
|
/* Convert the mask to string form. */
|
||||||
switch (family) {
|
switch (family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
sin = (struct sockaddr_in *)&ifr->ifr_addr;
|
sin4 = (struct sockaddr_in *)&ifr->ifr_addr;
|
||||||
if (inet_ntop(AF_INET, &sin->sin_addr, maskstr, sizeof(maskstr)) == NULL) {
|
if (inet_ntop(AF_INET, &sin4->sin_addr, maskstr, sizeof(maskstr)) == NULL) {
|
||||||
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
"ignoring bad AF_INET mask for %s", ifr->ifr_name);
|
"ignoring bad AF_INET mask for %s", ifr->ifr_name);
|
||||||
continue;
|
continue;
|
||||||
|
@@ -358,7 +358,7 @@ intercept_connect(void)
|
|||||||
{
|
{
|
||||||
int sock = -1;
|
int sock = -1;
|
||||||
int on = 1;
|
int on = 1;
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin4;
|
||||||
debug_decl(intercept_connect, SUDO_DEBUG_EXEC);
|
debug_decl(intercept_connect, SUDO_DEBUG_EXEC);
|
||||||
|
|
||||||
if (intercept_port == 0) {
|
if (intercept_port == 0) {
|
||||||
@@ -366,10 +366,10 @@ intercept_connect(void)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&sin, 0, sizeof(sin));
|
memset(&sin4, 0, sizeof(sin4));
|
||||||
sin.sin_family = AF_INET;
|
sin4.sin_family = AF_INET;
|
||||||
sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
sin4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||||
sin.sin_port = htons(intercept_port);
|
sin4.sin_port = htons(intercept_port);
|
||||||
|
|
||||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if (sock == -1) {
|
if (sock == -1) {
|
||||||
@@ -380,7 +380,7 @@ intercept_connect(void)
|
|||||||
/* Send data immediately, we need low latency IPC. */
|
/* Send data immediately, we need low latency IPC. */
|
||||||
(void)setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
|
(void)setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
|
||||||
|
|
||||||
if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
|
if (connect(sock, (struct sockaddr *)&sin4, sizeof(sin4)) == -1) {
|
||||||
sudo_warn("connect");
|
sudo_warn("connect");
|
||||||
close(sock);
|
close(sock);
|
||||||
sock = -1;
|
sock = -1;
|
||||||
|
@@ -38,7 +38,7 @@ struct policy_plugin_1_0 {
|
|||||||
unsigned int type;
|
unsigned int type;
|
||||||
unsigned int version;
|
unsigned int version;
|
||||||
int (*open)(unsigned int version, sudo_conv_1_7_t conversation,
|
int (*open)(unsigned int version, sudo_conv_1_7_t conversation,
|
||||||
sudo_printf_t sudo_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], char * const user_env[]);
|
char * const user_info[], char * const user_env[]);
|
||||||
void (*close)(int exit_status, int error); /* wait status or error */
|
void (*close)(int exit_status, int error); /* wait status or error */
|
||||||
int (*show_version)(int verbose);
|
int (*show_version)(int verbose);
|
||||||
@@ -46,16 +46,16 @@ struct policy_plugin_1_0 {
|
|||||||
char *env_add[], char **command_info[],
|
char *env_add[], char **command_info[],
|
||||||
char **argv_out[], char **user_env_out[]);
|
char **argv_out[], char **user_env_out[]);
|
||||||
int (*list)(int argc, char * const argv[], int verbose,
|
int (*list)(int argc, char * const argv[], int verbose,
|
||||||
const char *list_user);
|
const char *user);
|
||||||
int (*validate)(void);
|
int (*validate)(void);
|
||||||
void (*invalidate)(int remove);
|
void (*invalidate)(int rmcred);
|
||||||
int (*init_session)(struct passwd *pwd);
|
int (*init_session)(struct passwd *pwd);
|
||||||
};
|
};
|
||||||
struct io_plugin_1_0 {
|
struct io_plugin_1_0 {
|
||||||
unsigned int type;
|
unsigned int type;
|
||||||
unsigned int version;
|
unsigned int version;
|
||||||
int (*open)(unsigned int version, sudo_conv_1_7_t conversation,
|
int (*open)(unsigned int version, sudo_conv_1_7_t conversation,
|
||||||
sudo_printf_t sudo_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], int argc, char * const argv[],
|
char * const user_info[], int argc, char * const argv[],
|
||||||
char * const user_env[]);
|
char * const user_env[]);
|
||||||
void (*close)(int exit_status, int error);
|
void (*close)(int exit_status, int error);
|
||||||
@@ -70,7 +70,7 @@ struct io_plugin_1_1 {
|
|||||||
unsigned int type;
|
unsigned int type;
|
||||||
unsigned int version;
|
unsigned int version;
|
||||||
int (*open)(unsigned int version, sudo_conv_1_7_t conversation,
|
int (*open)(unsigned int version, sudo_conv_1_7_t conversation,
|
||||||
sudo_printf_t sudo_printf, char * const settings[],
|
sudo_printf_t sudo_plugin_printf, char * const settings[],
|
||||||
char * const user_info[], char * const command_info[],
|
char * const user_info[], char * const command_info[],
|
||||||
int argc, char * const argv[], char * const user_env[]);
|
int argc, char * const argv[], char * const user_env[]);
|
||||||
void (*close)(int exit_status, int error); /* wait status or error */
|
void (*close)(int exit_status, int error); /* wait status or error */
|
||||||
|
Reference in New Issue
Block a user