提交 0980764d 编写于 作者: C Cédric Bosdonnat

util: share code between virExec and virCommandExec

virCommand is a version of virExec that doesn't fork, however it is
just calling execve and doesn't honors setting uid/gid and pwd.

This commit extrac those pieces from virExec() to a virExecCommon()
function that is called from both virExec() and virCommandExec().
上级 25630a37
......@@ -464,6 +464,41 @@ virCommandHandshakeChild(virCommandPtr cmd)
return 0;
}
static int
virExecCommon(virCommandPtr cmd)
{
gid_t *groups = NULL;
int ngroups;
int ret = -1;
if ((ngroups = virGetGroupList(cmd->uid, cmd->gid, &groups)) < 0)
goto cleanup;
if (cmd->uid != (uid_t)-1 || cmd->gid != (gid_t)-1 ||
cmd->capabilities || (cmd->flags & VIR_EXEC_CLEAR_CAPS)) {
VIR_DEBUG("Setting child uid:gid to %d:%d with caps %llx",
(int)cmd->uid, (int)cmd->gid, cmd->capabilities);
if (virSetUIDGIDWithCaps(cmd->uid, cmd->gid, groups, ngroups,
cmd->capabilities,
!!(cmd->flags & VIR_EXEC_CLEAR_CAPS)) < 0)
goto cleanup;
}
if (cmd->pwd) {
VIR_DEBUG("Running child in %s", cmd->pwd);
if (chdir(cmd->pwd) < 0) {
virReportSystemError(errno,
_("Unable to change to %s"), cmd->pwd);
goto cleanup;
}
}
ret = 0;
cleanup:
VIR_FREE(groups);
return ret;
}
/*
* virExec:
* @cmd virCommandPtr containing all information about the program to
......@@ -484,8 +519,6 @@ virExec(virCommandPtr cmd)
const char *binary = NULL;
int ret;
struct sigaction waxon, waxoff;
gid_t *groups = NULL;
int ngroups;
if (cmd->args[0][0] != '/') {
if (!(binary = binarystr = virFindFileInPath(cmd->args[0]))) {
......@@ -556,9 +589,6 @@ virExec(virCommandPtr cmd)
childerr = null;
}
if ((ngroups = virGetGroupList(cmd->uid, cmd->gid, &groups)) < 0)
goto cleanup;
pid = virFork();
if (pid < 0)
......@@ -578,7 +608,6 @@ virExec(virCommandPtr cmd)
cmd->pid = pid;
VIR_FREE(binarystr);
VIR_FREE(groups);
return 0;
}
......@@ -727,28 +756,8 @@ virExec(virCommandPtr cmd)
}
# endif
/* The steps above may need to do something privileged, so we delay
* setuid and clearing capabilities until the last minute.
*/
if (cmd->uid != (uid_t)-1 || cmd->gid != (gid_t)-1 ||
cmd->capabilities || (cmd->flags & VIR_EXEC_CLEAR_CAPS)) {
VIR_DEBUG("Setting child uid:gid to %d:%d with caps %llx",
(int)cmd->uid, (int)cmd->gid, cmd->capabilities);
if (virSetUIDGIDWithCaps(cmd->uid, cmd->gid, groups, ngroups,
cmd->capabilities,
!!(cmd->flags & VIR_EXEC_CLEAR_CAPS)) < 0) {
goto fork_error;
}
}
if (cmd->pwd) {
VIR_DEBUG("Running child in %s", cmd->pwd);
if (chdir(cmd->pwd) < 0) {
virReportSystemError(errno,
_("Unable to change to %s"), cmd->pwd);
goto fork_error;
}
}
if (virExecCommon(cmd) < 0)
goto fork_error;
if (virCommandHandshakeChild(cmd) < 0)
goto fork_error;
......@@ -789,7 +798,6 @@ virExec(virCommandPtr cmd)
/* This is cleanup of parent process only - child
should never jump here on error */
VIR_FREE(groups);
VIR_FREE(binarystr);
/* NB we don't virReportError() on any failures here
......@@ -2166,6 +2174,9 @@ int virCommandExec(virCommandPtr cmd)
return -1;
}
if (virExecCommon(cmd) < 0)
return -1;
execve(cmd->args[0], cmd->args, cmd->env);
virReportSystemError(errno,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册