Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
uv_spawn: support setting the child process' user and group id
Browse files Browse the repository at this point in the history
  • Loading branch information
piscisaureus committed Apr 28, 2012
1 parent c862acc commit 99a995a
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 7 deletions.
5 changes: 5 additions & 0 deletions include/uv-private/uv-unix.h
Expand Up @@ -33,6 +33,7 @@
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <pwd.h>
#include <termios.h>
#include <pthread.h>

Expand All @@ -51,6 +52,10 @@ typedef pthread_t uv_thread_t;
typedef pthread_mutex_t uv_mutex_t;
typedef pthread_rwlock_t uv_rwlock_t;

/* Platform-specific definitions for uv_spawn support. */
typedef gid_t uv_gid_t;
typedef uid_t uv_uid_t;

/* Platform-specific definitions for uv_dlopen support. */
typedef void* uv_lib_t;
#define UV_DYNAMIC /* empty */
Expand Down
4 changes: 4 additions & 0 deletions include/uv-private/uv-win.h
Expand Up @@ -165,6 +165,10 @@ typedef struct uv_once_s {
HANDLE padding;
} uv_once_t;

/* Platform-specific definitions for uv_spawn support. */
typedef unsigned char uv_uid_t;
typedef unsigned char uv_gid_t;

/* Platform-specific definitions for uv_dlopen support. */
typedef HMODULE uv_lib_t;
#define UV_DYNAMIC FAR WINAPI
Expand Down
39 changes: 35 additions & 4 deletions include/uv.h
Expand Up @@ -1105,12 +1105,18 @@ typedef struct uv_process_options_s {
* in. Stands for current working directory.
*/
char* cwd;

/*
* TODO describe how this works.
* Various flags that control how uv_spawn() behaves. See the definition of
* `enum uv_process_flags` below.
*/
int windows_verbatim_arguments;

unsigned int flags;
/*
* Libuv can change the child process' user/group id. This happens only when
* the appropriate bits are set in the flags fields. This is not supported on
* windows; uv_spawn() will fail and set the error to UV_ENOTSUP.
*/
uv_uid_t uid;
uv_gid_t gid;
/*
* The user should supply pointers to initialized uv_pipe_t structs for
* stdio. This is used to to send or receive input from the subprocess.
Expand All @@ -1121,6 +1127,30 @@ typedef struct uv_process_options_s {
uv_pipe_t* stderr_stream;
} uv_process_options_t;

/*
* These are the flags that can be used for the uv_process_options.flags field.
*/
enum uv_process_flags {
/*
* Set the child process' user id. The user id is supplied in the `uid` field
* of the options struct. This does not work on windows; setting this flag
* will cause uv_spawn() to fail.
*/
UV_PROCESS_SETUID = (1 << 0),
/*
* Set the child process' group id. The user id is supplied in the `gid`
* field of the options struct. This does not work on windows; setting this
* flag will cause uv_spawn() to fail.
*/
UV_PROCESS_SETGID = (1 << 1),
/*
* Do not wrap any arguments in quotes, or perform any other escaping, when
* converting the argument list into a command line string. This option is
* only meaningful on Windows systems. On unix it is silently ignored.
*/
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS = (1 << 2)
};

/*
* uv_process_t is a subclass of uv_handle_t
*/
Expand All @@ -1135,6 +1165,7 @@ struct uv_process_s {
UV_EXTERN int uv_spawn(uv_loop_t*, uv_process_t*,
uv_process_options_t options);


/*
* Kills the process with the specified signal. The user must still
* call uv_close on the process.
Expand Down
16 changes: 16 additions & 0 deletions src/unix/process.c
Expand Up @@ -174,6 +174,12 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
pid_t pid;
int flags;

assert(options.file != NULL);
assert(!(options.flags & ~(UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS |
UV_PROCESS_SETGID |
UV_PROCESS_SETUID)));


uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS);
loop->counters.process_init++;

Expand Down Expand Up @@ -263,6 +269,16 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
_exit(127);
}

if ((options.flags & UV_PROCESS_SETGID) && setgid(options.gid)) {
perror("setgid()");
_exit(127);
}

if ((options.flags & UV_PROCESS_SETUID) && setuid(options.uid)) {
perror("setuid()");
_exit(127);
}

environ = options.env;

execvp(options.file, options.args);
Expand Down
11 changes: 8 additions & 3 deletions src/win/process.c
Expand Up @@ -872,17 +872,22 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
STARTUPINFOW startup;
PROCESS_INFORMATION info;

if (!options.file) {
uv__set_artificial_error(loop, UV_EINVAL);
if (options.flags & (UV_PROCESS_SETGID | UV_PROCESS_SETUID)) {
uv__set_artificial_error(loop, UV_ENOTSUP);
return -1;
}

assert(options.file != NULL);
assert(!(options.flags & ~(UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS |
UV_PROCESS_SETGID |
UV_PROCESS_SETUID)));

uv_process_init(loop, process);

process->exit_cb = options.exit_cb;
UTF8_TO_UTF16(options.file, application);
arguments = options.args ? make_program_args(options.args,
options.windows_verbatim_arguments) : NULL;
options.flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS) : NULL;
env = options.env ? make_program_env(options.env) : NULL;

if (options.cwd) {
Expand Down

0 comments on commit 99a995a

Please sign in to comment.