X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fexec.c;h=e5c5df9f3eef09dc6102bfdd475302cf08d05d04;hb=2b95935417aa46534bf986c06a8723e0af32d63f;hp=94d0b987b0b8120972a00b98fd39886ba1b2cdd3;hpb=5911e6e2228899b461211bea37c2480c339fa2e1;p=collectd.git diff --git a/src/exec.c b/src/exec.c index 94d0b987..e5c5df9f 100644 --- a/src/exec.c +++ b/src/exec.c @@ -346,64 +346,11 @@ static void close_pipe(int fd_pipe[2]) /* {{{ */ } /* }}} void close_pipe */ /* - * Creates three pipes (one for reading, one for writing and one for errors), - * forks a child, sets up the pipes so that fd_in is connected to STDIN of - * the child and fd_out is connected to STDOUT and fd_err is connected to STDERR - * of the child. Then is calls `exec_child'. + * Get effective group ID from group name. */ -static int fork_child(program_list_t *pl, int *fd_in, int *fd_out, - int *fd_err) /* {{{ */ +static int getegr_id(program_list_t *pl, int gid) /* {{{ */ { - int fd_pipe_in[2] = {-1, -1}; - int fd_pipe_out[2] = {-1, -1}; - int fd_pipe_err[2] = {-1, -1}; - int status; - int pid; - - int uid; - int gid; - int egid; - - struct passwd *sp_ptr; - struct passwd sp; - - if (pl->pid != 0) - return -1; - - long int nambuf_size = sysconf(_SC_GETPW_R_SIZE_MAX); - if (nambuf_size <= 0) - nambuf_size = sysconf(_SC_PAGESIZE); - if (nambuf_size <= 0) - nambuf_size = 4096; - char nambuf[nambuf_size]; - - if ((create_pipe(fd_pipe_in) == -1) || (create_pipe(fd_pipe_out) == -1) || - (create_pipe(fd_pipe_err) == -1)) - goto failed; - - sp_ptr = NULL; - status = getpwnam_r(pl->user, &sp, nambuf, sizeof(nambuf), &sp_ptr); - if (status != 0) { - ERROR("exec plugin: Failed to get user information for user ``%s'': %s", - pl->user, STRERROR(status)); - goto failed; - } - - if (sp_ptr == NULL) { - ERROR("exec plugin: No such user: `%s'", pl->user); - goto failed; - } - - uid = sp.pw_uid; - gid = sp.pw_gid; - if (uid == 0) { - ERROR("exec plugin: Cowardly refusing to exec program as root."); - goto failed; - } - - /* The group configured in the configfile is set as effective group, because - * this way the forked process can (re-)gain the user's primary group. */ - egid = -1; + int egid = -1; if (pl->group != NULL) { if (*pl->group != '\0') { struct group *gr_ptr = NULL; @@ -471,12 +418,78 @@ static int fork_child(program_list_t *pl, int *fd_in, int *fd_out, DEBUG("exec plugin: release grbuf memory "); grbuf = NULL; if (getgr_failed > 0) { - goto failed; + egid = -2; // arbitrary value to indicate fail } } else { egid = gid; } } /* if (pl->group == NULL) */ + return egid; +} + +/* + * Creates three pipes (one for reading, one for writing and one for errors), + * forks a child, sets up the pipes so that fd_in is connected to STDIN of + * the child and fd_out is connected to STDOUT and fd_err is connected to STDERR + * of the child. Then is calls `exec_child'. + */ +static int fork_child(program_list_t *pl, int *fd_in, int *fd_out, + int *fd_err) /* {{{ */ +{ + int fd_pipe_in[2] = {-1, -1}; + int fd_pipe_out[2] = {-1, -1}; + int fd_pipe_err[2] = {-1, -1}; + int status; + int pid; + + int uid; + int gid; + int egid; + + struct passwd *sp_ptr; + struct passwd sp; + + if (pl->pid != 0) + return -1; + + long int nambuf_size = sysconf(_SC_GETPW_R_SIZE_MAX); + if (nambuf_size <= 0) + nambuf_size = sysconf(_SC_PAGESIZE); + if (nambuf_size <= 0) + nambuf_size = 4096; + char nambuf[nambuf_size]; + + if ((create_pipe(fd_pipe_in) == -1) || (create_pipe(fd_pipe_out) == -1) || + (create_pipe(fd_pipe_err) == -1)) + goto failed; + + sp_ptr = NULL; + status = getpwnam_r(pl->user, &sp, nambuf, sizeof(nambuf), &sp_ptr); + if (status != 0) { + ERROR("exec plugin: Failed to get user information for user ``%s'': %s", + pl->user, STRERROR(status)); + goto failed; + } + + if (sp_ptr == NULL) { + ERROR("exec plugin: No such user: `%s'", pl->user); + goto failed; + } + + uid = sp.pw_uid; + gid = sp.pw_gid; + if (uid == 0) { + ERROR("exec plugin: Cowardly refusing to exec program as root."); + goto failed; + } + + /* The group configured in the configfile is set as effective group, because + * this way the forked process can (re-)gain the user's primary group. */ + egid = getegr_id(pl, gid); + if (egid <= -2) { + ERROR("exec plugin: getegr_id failed: %s", STRERRNO); + goto failed; + } pid = fork(); if (pid < 0) {