mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-04-01 20:05:19 +00:00
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().
This commit is contained in:
parent
25630a3735
commit
0980764dee
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user