The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Macros | Functions | Variables
exec.c File Reference

Execute external programs. More...

#include <stdint.h>
#include <freeradius-devel/server/log.h>
#include <freeradius-devel/server/exec.h>
#include <freeradius-devel/server/exec_priv.h>
#include <freeradius-devel/server/request.h>
#include <freeradius-devel/server/util.h>
#include <freeradius-devel/util/debug.h>
+ Include dependency graph for exec.c:

Go to the source code of this file.

Macros

#define MAX_ENVP   1024
 

Functions

static char ** exec_build_env (char **env_in, bool env_inherit)
 Merge extra environmental variables and potentially the inherited environment. More...
 
static NEVER_RETURNS void exec_child (char **argv, char **envp, bool exec_wait, bool debug, int stdin_pipe[static 2], int stdout_pipe[static 2], int stderr_pipe[static 2])
 Start a child process. More...
 
static void exec_debug (request_t *request, char **argv_in, char **env_in, bool env_inherit)
 Print debug information showing the arguments and environment for a process. More...
 
static int exec_pair_to_env (char **env_p, size_t env_len, fr_sbuff_t *env_sbuff, fr_sbuff_marker_t env_m[], request_t *request, fr_pair_list_t *env_pairs, bool env_escape)
 Convert pairs from a request and a list of pairs into environmental variables. More...
 
static void exec_reap (fr_event_list_t *el, pid_t pid, int status, void *uctx)
 
static void exec_stdout_read (UNUSED fr_event_list_t *el, int fd, int flags, void *uctx)
 
static void exec_timeout (UNUSED fr_event_list_t *el, UNUSED fr_time_t now, void *uctx)
 
int fr_exec_fork_nowait (fr_event_list_t *el, char **argv_in, char **env_in, bool env_inherit, bool debug)
 Execute a program without waiting for the program to finish. More...
 
int fr_exec_fork_wait (pid_t *pid_p, int *stdin_fd, int *stdout_fd, int *stderr_fd, char **argv_in, char **env_in, bool env_inherit, bool debug)
 Execute a program assuming that the caller waits for it to finish. More...
 
int fr_exec_oneshot (TALLOC_CTX *ctx, fr_exec_state_t *exec, request_t *request, fr_value_box_list_t *args, fr_pair_list_t *env_pairs, bool env_escape, bool env_inherit, bool need_stdin, bool store_stdout, TALLOC_CTX *stdout_ctx, fr_time_delta_t timeout)
 Call an child program, optionally reading it's output. More...
 
void fr_exec_oneshot_cleanup (fr_exec_state_t *exec, int signal)
 Cleans up an exec'd process on error. More...
 
int fr_exec_oneshot_nowait (request_t *request, fr_value_box_list_t *args, fr_pair_list_t *env_pairs, bool env_escape, bool env_inherit)
 Similar to fr_exec_oneshot, but does not attempt to parse output. More...
 
char ** fr_exec_pair_to_env (request_t *request, fr_pair_list_t *env_pairs, bool env_escape)
 Convert env_pairs into an array of environmental variables using thread local buffers. More...
 
int fr_exec_value_box_list_to_argv (TALLOC_CTX *ctx, char ***argv_p, fr_value_box_list_t const *in)
 Flatten a list into individual "char *" argv-style array. More...
 

Variables

static _Thread_local char * env_exec_arr [MAX_ENVP]
 

Detailed Description

Execute external programs.

Id
c32377b47d41e19fd92ea59479c6839c11b98b90

Definition in file exec.c.

Macro Definition Documentation

◆ MAX_ENVP

#define MAX_ENVP   1024

Definition at line 37 of file exec.c.

Function Documentation

◆ exec_build_env()

static char** exec_build_env ( char **  env_in,
bool  env_inherit 
)
static

Merge extra environmental variables and potentially the inherited environment.

Parameters
[in]env_into merge.
[in]env_inheritinherite environment from radiusd.
Returns
merged environmental variables.

Definition at line 401 of file exec.c.

+ Here is the caller graph for this function:

◆ exec_child()

static NEVER_RETURNS void exec_child ( char **  argv,
char **  envp,
bool  exec_wait,
bool  debug,
int  stdin_pipe[static 2],
int  stdout_pipe[static 2],
int  stderr_pipe[static 2] 
)
static

Start a child process.

We try to be fail-safe here. So if ANYTHING goes wrong, we exit with status 1.

Parameters
[in]argvarray of arguments to pass to child.
[in]envparray of environment variables in form <attr>=<val>
[in]exec_waitif true, redirect child process' stdin, stdout, stderr to the pipes provided, redirecting any to /dev/null where no pipe was provided. If false redirect stdin, and stdout to /dev/null.
[in]debugIf true, and !exec_wait, don't molest stderr.
[in]stdin_pipethe pipe used to write data to the process. STDIN will be set to stdin_pipe[0], stdin_pipe[1] will be closed.
[in]stdout_pipethe pipe used to read data from the process. STDOUT will be set to stdout_pipe[1], stdout_pipe[0] will be closed.
[in]stderr_pipethe pipe used to read error text from the process. STDERR will be set to stderr_pipe[1], stderr_pip[0] will be closed.

Definition at line 291 of file exec.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ exec_debug()

static void exec_debug ( request_t request,
char **  argv_in,
char **  env_in,
bool  env_inherit 
)
inlinestatic

Print debug information showing the arguments and environment for a process.

Parameters
[in]requestThe current request, may be NULL.
[in]argv_inarguments to pass to process.
[in]env_inenvironment to pass to process.
[in]env_inheritprint debug for the environment from the environment.

Definition at line 95 of file exec.c.

+ Here is the caller graph for this function:

◆ exec_pair_to_env()

static int exec_pair_to_env ( char **  env_p,
size_t  env_len,
fr_sbuff_t env_sbuff,
fr_sbuff_marker_t  env_m[],
request_t request,
fr_pair_list_t env_pairs,
bool  env_escape 
)
inlinestatic

Convert pairs from a request and a list of pairs into environmental variables.

Parameters
[out]env_pWhere to write an array of \0 terminated strings.
[in]env_lenLength of env_p.
[out]env_sbuffTo write environmental variables too. Each variable will be written to the buffer, and separated with a '\0'.
[in]env_man array of markers of the same length as env_len.
[in]requestWill look for &control.Exec-Export items to convert to env vars.
[in]env_pairsOther items to convert to environmental variables. The dictionary attribute name will be converted to uppercase, and all '-' converted to '_' and will form the variable name.
[in]env_escapeWrap string values in double quotes, and apply doublequote escaping to all environmental variable values.
Returns
  • The number of environmental variables created.
  • -1 on failure.

Definition at line 125 of file exec.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ exec_reap()

static void exec_reap ( fr_event_list_t el,
pid_t  pid,
int  status,
void *  uctx 
)
static

Definition at line 726 of file exec.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ exec_stdout_read()

static void exec_stdout_read ( UNUSED fr_event_list_t el,
int  fd,
int  flags,
void *  uctx 
)
static

Definition at line 876 of file exec.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ exec_timeout()

static void exec_timeout ( UNUSED fr_event_list_t el,
UNUSED fr_time_t  now,
void *  uctx 
)
static

Definition at line 847 of file exec.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_exec_fork_nowait()

int fr_exec_fork_nowait ( fr_event_list_t el,
char **  argv_in,
char **  env_in,
bool  env_inherit,
bool  debug 
)

Execute a program without waiting for the program to finish.

Parameters
[in]elevent list to insert reaper child into.
[in]argv_inarg[0] is the path to the program, arg[...] are arguments to pass to the program.
[in]env_inany additional environmental variables to pass to the program.
[in]env_inheritInherit the environment from the current process. This will be merged with any variables from env_pairs.
[in]debugIf true, STDERR will be left open and pointing to the stderr descriptor of the parent.
Returns
Todo:
  • maybe take an fr_dcursor_t instead of env_pairs? That would allow finer-grained control over the attributes to put into the environment.

Definition at line 461 of file exec.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_exec_fork_wait()

int fr_exec_fork_wait ( pid_t *  pid_p,
int *  stdin_fd,
int *  stdout_fd,
int *  stderr_fd,
char **  argv_in,
char **  env_in,
bool  env_inherit,
bool  debug 
)

Execute a program assuming that the caller waits for it to finish.

The caller takes responsibility for calling waitpid() on the returned PID.

The caller takes responsibility for reading from the returned FD, and closing it.

Parameters
[out]pid_pThe PID of the child
[out]stdin_fdThe stdin FD of the child.
[out]stdout_fdThe stdout FD of the child.
[out]stderr_fdThe stderr FD of the child.
[in]argv_inarg[0] is the path to the program, arg[...] are arguments to pass to the program.
[in]env_inEnvironmental variables to pass to the program.
[in]env_inheritInherit the environment from the current process. This will be merged with any variables from env_pairs.
[in]debugIf true, STDERR will be left open and pointing to the stderr descriptor of the parent, if no stderr_fd pointer is provided.
Returns
Todo:
  • maybe take an fr_dcursor_t instead of env_pairs? That would allow finer-grained control over the attributes to put into the environment.

Definition at line 528 of file exec.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_exec_oneshot()

int fr_exec_oneshot ( TALLOC_CTX *  ctx,
fr_exec_state_t exec,
request_t request,
fr_value_box_list_t *  args,
fr_pair_list_t env_pairs,
bool  env_escape,
bool  env_inherit,
bool  need_stdin,
bool  store_stdout,
TALLOC_CTX *  stdout_ctx,
fr_time_delta_t  timeout 
)

Call an child program, optionally reading it's output.

Note
If the caller set need_stdin = true, it is the caller's responsibility to close exec->std_in and remove it from any event loops if this function returns 0 (success).
Parameters
[in]ctxto allocate events in.
[in,out]execstructure holding the state of the external call.
[in]requestcurrently being processed, may be NULL.
[in]argsto call as a fr_value_box_list_t. Program will be the first box and arguments in the subsequent boxes.
[in]env_pairslist of pairs to be presented as environment variables to the child.
[in]env_escapeWrap string values in double quotes, and apply doublequote escaping to all environmental variable values.
[in]env_inheritInherit the environment from the current process. This will be merged with any variables from env_pairs.
[in]need_stdinIf true, allocate a pipe that will allow us to send data to the process.
[in]store_stdoutif true keep a copy of stdout in addition to logging it if RDEBUG_ENABLED2.
[in]stdout_ctxctx to alloc stdout data in.
[in]timeoutto wait for child to complete.
Returns
  • 0 on success
  • -1 on failure

Definition at line 984 of file exec.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_exec_oneshot_cleanup()

void fr_exec_oneshot_cleanup ( fr_exec_state_t exec,
int  signal 
)

Cleans up an exec'd process on error.

This function is intended to be called at any point after a successful fr_exec_oneshot call in order to release resources and cleanup zombie processes.

Parameters
[in]execstate to cleanup.
[in]signalIf non-zero, and we think the process is still running, send it a signal to cause it to exit. The PID reaper we insert here will cleanup its state so it doesn't become a zombie.

Definition at line 666 of file exec.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_exec_oneshot_nowait()

int fr_exec_oneshot_nowait ( request_t request,
fr_value_box_list_t *  args,
fr_pair_list_t env_pairs,
bool  env_escape,
bool  env_inherit 
)

Similar to fr_exec_oneshot, but does not attempt to parse output.

Parameters
[in]requestcurrently being processed, may be NULL.
[in]argsto call as a fr_value_box_list_t. Program will be the first box and arguments in the subsequent boxes.
[in]env_pairslist of pairs to be presented as environment variables to the child.
[in]env_escapeWrap string values in double quotes, and apply doublequote escaping to all environmental variable values.
[in]env_inheritInherit the environment from the current process. This will be merged with any variables from env_pairs.
Returns
  • 0 on success.
  • -1 on error.

Definition at line 623 of file exec.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_exec_pair_to_env()

char** fr_exec_pair_to_env ( request_t request,
fr_pair_list_t env_pairs,
bool  env_escape 
)

Convert env_pairs into an array of environmental variables using thread local buffers.

Parameters
[in]requestWill be searched for control.Exec-Export pairs.
[in]env_pairsenv_pairs to put into into the environment. May be NULL.
[in]env_escapeWrap string values in double quotes, and apply doublequote escaping to all environmental variable values.
Returns
  • An array of environmental variable definitions, valid until the next call to fr_exec_pair_to_env within the same thread.
  • NULL on error. Error retrievable fr_strerror().

Definition at line 258 of file exec.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fr_exec_value_box_list_to_argv()

int fr_exec_value_box_list_to_argv ( TALLOC_CTX *  ctx,
char ***  argv_p,
fr_value_box_list_t const *  in 
)

Flatten a list into individual "char *" argv-style array.

Parameters
[in]ctxto allocate boxes in.
[out]argv_pwhere output strings go
[in]inboxes to flatten
Returns
  • >= 0 number of array elements in argv
  • <0 on error

Definition at line 50 of file exec.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ env_exec_arr

_Thread_local char* env_exec_arr[MAX_ENVP]
static

Definition at line 39 of file exec.c.